/*
 *******************************************************************************
 * Copyright (c) 2019 Contributors to the Eclipse Foundation
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0
 *******************************************************************************
 */
package org.eclipse.openk.contactbasedata.service;

import org.eclipse.openk.contactbasedata.config.TestConfiguration;
import org.eclipse.openk.contactbasedata.exceptions.NotFoundException;
import org.eclipse.openk.contactbasedata.model.RefPersonType;
import org.eclipse.openk.contactbasedata.model.RefSalutation;
import org.eclipse.openk.contactbasedata.model.TblContact;
import org.eclipse.openk.contactbasedata.model.TblExternalPerson;
import org.eclipse.openk.contactbasedata.repository.ContactRepository;
import org.eclipse.openk.contactbasedata.repository.ExternalPersonRepository;
import org.eclipse.openk.contactbasedata.repository.PersonTypeRepository;
import org.eclipse.openk.contactbasedata.repository.SalutationRepository;
import org.eclipse.openk.contactbasedata.support.MockDataHelper;
import org.eclipse.openk.contactbasedata.viewmodel.ExternalPersonDto;
import org.junit.jupiter.api.Test;
import org.mockito.stubbing.Answer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;

import java.util.Optional;
import java.util.UUID;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@DataJpaTest
@ContextConfiguration(classes = {TestConfiguration.class})
@ActiveProfiles("test")
class ExternalPersonServiceTest {
    @Qualifier("myExternalPersonService")
    @Autowired
    private ExternalPersonService externalPersonService;

    @MockBean
    private ExternalPersonRepository externalPersonRepository;

    @MockBean
    private ContactRepository contactRepository;

    @MockBean
    private SalutationRepository salutationRepository;

    @MockBean
    private PersonTypeRepository personTypeRepository;

    @Test
    void shouldFindAnExternalPersonProperly() {
        TblExternalPerson ep = MockDataHelper.mockExternalPerson();
        when(externalPersonRepository.findByTblContactUuid(any(UUID.class))).thenReturn(Optional.of(ep));
        ExternalPersonDto dto = externalPersonService.findExternalPerson(UUID.randomUUID());

        assertEquals(ep.getContact().getUuid(), dto.getContactUuid());
    }

    @Test
    void shouldFindSeveralExternalPersonsProperly() {
        Page<TblExternalPerson> page1 = MockDataHelper.mockExternalPersonPage();
        Page<TblExternalPerson> page2 = MockDataHelper.mockExternalPersonPage();
        when(externalPersonRepository.findAll(any(Pageable.class))).thenReturn(page1);
        when(externalPersonRepository.findByContact_anonymizedFalseOrContact_anonymizedIsNull(any(Pageable.class))).thenReturn(page2);
        Page<ExternalPersonDto> dtos1 = externalPersonService.findExternalPersons(true, Pageable.unpaged());
        Page<ExternalPersonDto> dtos2 = externalPersonService.findExternalPersons(false, Pageable.unpaged());

        assertEquals(page1.getContent().get(0).getContact().getUuid(), dtos1.get().findFirst().get().getContactUuid());
        assertEquals(page2.getContent().get(1).getContact().getUuid(), dtos2.getContent().get(1).getContactUuid());
        assertNotEquals(dtos1.getContent().get(0).getContactUuid(), dtos2.getContent().get(0).getContactUuid());

        verify(externalPersonRepository, times(1)).findAll(any(Pageable.class));
        verify(externalPersonRepository, times(1))
                .findByContact_anonymizedFalseOrContact_anonymizedIsNull(any(Pageable.class));
    }

    @Test
    void shouldThrowInErrorCaseWithExternalPerson() {
        TblExternalPerson ep = MockDataHelper.mockExternalPerson();
        when(externalPersonRepository.findByTblContactUuid(any(UUID.class))).thenReturn(Optional.empty());
        assertThrows(NotFoundException.class, () -> externalPersonService.findExternalPerson(UUID.randomUUID()));
    }

    @Test
    void shouldUpdateExternalPerson() {
        ExternalPersonDto epDto = MockDataHelper.mockExternalPersonDto();
        TblExternalPerson epTbl = MockDataHelper.mockExternalPerson();
        when(externalPersonRepository.findByTblContactUuid(any(UUID.class))).thenReturn(Optional.of(epTbl));
        when(salutationRepository.findByUuid(any(UUID.class)))
                .thenReturn(Optional.of(MockDataHelper.mockRefSalutation()));
        when(personTypeRepository.findByUuid(any(UUID.class)))
                .thenReturn(Optional.of(MockDataHelper.mockRefPersonType()));

        when(externalPersonRepository.save(any(TblExternalPerson.class)))
                .then((Answer<TblExternalPerson>) invocation -> {
                    Object[] args = invocation.getArguments();
                    return (TblExternalPerson) args[0];
                });

        ExternalPersonDto savedDto = externalPersonService.updateExternalPerson(epDto);
        assertEquals(epTbl.getContact().getUuid(), savedDto.getContactUuid());
        assertEquals(epTbl.getContact().getNote(), savedDto.getContactNote());
        assertEquals(epTbl.getContact().getContactType(), savedDto.getContactType());
        assertEquals(epTbl.getFirstName(), savedDto.getFirstName());
        assertEquals(epTbl.getLastName(), savedDto.getLastName());
        assertEquals(epTbl.getTitle(), savedDto.getTitle());
        assertEquals(epTbl.getRefPersonType().getUuid(), savedDto.getPersonTypeUuid());
        assertEquals(epTbl.getSalutation().getUuid(), savedDto.getSalutationUuid());
    }

    @Test
    void shouldNotUpdateExternalPerson_Exception1() {
        ExternalPersonDto epDto = MockDataHelper.mockExternalPersonDto();
        TblExternalPerson epTbl = MockDataHelper.mockExternalPerson();
        when(externalPersonRepository.findByTblContactUuid(any(UUID.class))).thenReturn(Optional.empty());
        when(salutationRepository.findByUuid(any(UUID.class)))
                .thenReturn(Optional.of(MockDataHelper.mockRefSalutation()));
        when(personTypeRepository.findByUuid(any(UUID.class)))
                .thenReturn(Optional.of(MockDataHelper.mockRefPersonType()));

        when(externalPersonRepository.save(any(TblExternalPerson.class)))
                .then((Answer<TblExternalPerson>) invocation -> {
                    Object[] args = invocation.getArguments();
                    return (TblExternalPerson) args[0];
                });

        assertThrows( NotFoundException.class, () -> externalPersonService.updateExternalPerson(epDto));
    }

    @Test
    void shouldNotUpdateExternalPerson_Exception2() {
        ExternalPersonDto epDto = MockDataHelper.mockExternalPersonDto();
        TblExternalPerson epTbl = MockDataHelper.mockExternalPerson();
        when(externalPersonRepository.findByTblContactUuid(any(UUID.class))).thenReturn(Optional.of(epTbl));
        when(salutationRepository.findByUuid(any(UUID.class)))
                .thenReturn(Optional.empty());
        when(personTypeRepository.findByUuid(any(UUID.class)))
                .thenReturn(Optional.of(MockDataHelper.mockRefPersonType()));

        when(externalPersonRepository.save(any(TblExternalPerson.class)))
                .then((Answer<TblExternalPerson>) invocation -> {
                    Object[] args = invocation.getArguments();
                    return (TblExternalPerson) args[0];
                });

        assertThrows( NotFoundException.class, () -> externalPersonService.updateExternalPerson(epDto));
    }
    @Test
    void shouldNotUpdateExternalPerson_Exception3() {
        ExternalPersonDto epDto = MockDataHelper.mockExternalPersonDto();
        TblExternalPerson epTbl = MockDataHelper.mockExternalPerson();
        when(externalPersonRepository.findByTblContactUuid(any(UUID.class))).thenReturn(Optional.of(epTbl));
        when(salutationRepository.findByUuid(any(UUID.class)))
                .thenReturn(Optional.of(MockDataHelper.mockRefSalutation()));
        when(personTypeRepository.findByUuid(any(UUID.class)))
                .thenReturn(Optional.empty());

        when(externalPersonRepository.save(any(TblExternalPerson.class)))
                .then((Answer<TblExternalPerson>) invocation -> {
                    Object[] args = invocation.getArguments();
                    return (TblExternalPerson) args[0];
                });

        assertThrows( NotFoundException.class, () -> externalPersonService.updateExternalPerson(epDto));
    }

    @Test
    void shouldInsertExternalPerson() {
        ExternalPersonDto epDto = MockDataHelper.mockExternalPersonDto();
        epDto.setContactUuid(null);
        RefSalutation refSalutation = MockDataHelper.mockRefSalutation();
        when(salutationRepository.findByUuid(any(UUID.class)))
                .thenReturn(Optional.of(refSalutation));
        RefPersonType refPersonType = MockDataHelper.mockRefPersonType();
        when(personTypeRepository.findByUuid(any(UUID.class)))
                .thenReturn(Optional.of(refPersonType));
        when(contactRepository.save(any(TblContact.class)))
                .then((Answer<TblContact>) invocation -> {
                    Object[] args = invocation.getArguments();
                    return (TblContact) args[0];
                });
        when(externalPersonRepository.save(any(TblExternalPerson.class)))
                .then((Answer<TblExternalPerson>) invocation -> {
                    Object[] args = invocation.getArguments();
                    return (TblExternalPerson) args[0];
                });

        ExternalPersonDto savedDto = externalPersonService.insertExternalPerson(epDto);
        assertNotNull(savedDto.getContactUuid());
        assertEquals(epDto.getContactNote(), savedDto.getContactNote());
        assertEquals(epDto.getContactType(), savedDto.getContactType());
        assertEquals(epDto.getFirstName(), savedDto.getFirstName());
        assertEquals(epDto.getLastName(), savedDto.getLastName());
        assertEquals(epDto.getTitle(), savedDto.getTitle());
        assertEquals(refPersonType.getUuid(), savedDto.getPersonTypeUuid());
        assertEquals(refSalutation.getUuid(), savedDto.getSalutationUuid());
    }
}