/*
 *******************************************************************************
 * 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.ContextConfiguration;

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

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;

@DataJpaTest
@ContextConfiguration(classes = {TestConfiguration.class})

public 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
    public 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
    public 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
    public void shouldThrowInErrorCaseWithExternalPerson() {
        TblExternalPerson ep = MockDataHelper.mockExternalPerson();
        when(externalPersonRepository.findByTblContactUuid(any(UUID.class))).thenReturn(Optional.empty());
        assertThrows(NotFoundException.class, () -> externalPersonService.findExternalPerson(UUID.randomUUID()));
    }

    @Test
    public 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
    public 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
    public 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
    public 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
    public 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());
    }
}