/*
 *******************************************************************************
 * 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.TblCompany;
import org.eclipse.openk.contactbasedata.model.TblContact;
import org.eclipse.openk.contactbasedata.repository.CompanyRepository;
import org.eclipse.openk.contactbasedata.repository.ContactRepository;
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.CompanyDto;
import org.eclipse.openk.contactbasedata.viewmodel.ContactPersonDto;
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.List;
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 CompanyServiceTest {
    @Qualifier("myCompanyService")
    @Autowired
    private CompanyService companyService;

    @MockBean
    private CompanyRepository companyRepository;

    @MockBean
    private ContactRepository contactRepository;

    @MockBean
    private SalutationRepository salutationRepository;

    @MockBean
    private PersonTypeRepository personTypeRepository;

    @Test
    void shouldFindACompanyProperly() {
        TblCompany ep = MockDataHelper.mockCompany();
        when(companyRepository.findByTblContactUuid(any(UUID.class))).thenReturn(Optional.of(ep));
        CompanyDto dto = companyService.findCompany(UUID.randomUUID());

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


    @Test
    void shouldFindSeveralCompaniesProperly() {
        Page<TblCompany> page1 = MockDataHelper.mockCompanyPage();
        Page<TblCompany> page2 = MockDataHelper.mockCompanyPage();
        when(companyRepository.findAll(any(Pageable.class))).thenReturn(page1);
        when(companyRepository.findByContact_anonymizedFalseOrContact_anonymizedIsNull(any(Pageable.class))).thenReturn(page2);
        Page<CompanyDto> dtos1 = companyService.findCompanies(true, Pageable.unpaged());
        Page<CompanyDto> dtos2 = companyService.findCompanies(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(companyRepository, times(1)).findAll(any(Pageable.class));
        verify(companyRepository, times(1))
                .findByContact_anonymizedFalseOrContact_anonymizedIsNull(any(Pageable.class));
    }
    @Test
    void shouldThrowInErrorCaseWithCompany() {
        TblCompany ep = MockDataHelper.mockCompany();
        when(companyRepository.findByTblContactUuid(any(UUID.class))).thenReturn(Optional.empty());
        assertThrows(NotFoundException.class, () -> companyService.findCompany(UUID.randomUUID()));
    }

    @Test
    void shouldUpdateCompany() {
        CompanyDto epDto = MockDataHelper.mockCompanyDto();
        TblCompany epTbl = MockDataHelper.mockCompany();
        when(companyRepository.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(companyRepository.save(any(TblCompany.class)))
                .then((Answer<TblCompany>) invocation -> {
                    Object[] args = invocation.getArguments();
                    return (TblCompany) args[0];
                });

        CompanyDto savedDto = companyService.updateCompany(epDto);
        assertEquals(epTbl.getContact().getUuid(), savedDto.getContactUuid());
        assertEquals(epTbl.getContact().getNote(), savedDto.getContactNote());
        assertEquals(epTbl.getContact().getContactType(), savedDto.getContactType());
        assertEquals(epTbl.getCompanyName(), savedDto.getCompanyName());
        assertEquals(epTbl.getCompanyType(), savedDto.getCompanyType());
    }

    @Test
    void shouldNotUpdateCompany_Exception1() {
        CompanyDto epDto = MockDataHelper.mockCompanyDto();
        TblCompany epTbl = MockDataHelper.mockCompany();
        when(companyRepository.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(companyRepository.save(any(TblCompany.class)))
                .then((Answer<TblCompany>) invocation -> {
                    Object[] args = invocation.getArguments();
                    return (TblCompany) args[0];
                });

        assertThrows( NotFoundException.class, () -> companyService.updateCompany(epDto));
    }

    @Test
    void shouldInsertCompany() {
        CompanyDto epDto = MockDataHelper.mockCompanyDto();
        epDto.setContactUuid(null);

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

        CompanyDto savedDto = companyService.insertCompany(epDto);
        assertNotNull(savedDto.getContactUuid());
        assertEquals(epDto.getContactNote(), savedDto.getContactNote());
        assertEquals(epDto.getContactType(), savedDto.getContactType());
        assertEquals(epDto.getCompanyName(), savedDto.getCompanyName());
        assertEquals(epDto.getCompanyType(), savedDto.getCompanyType());
    }

    @Test
    void findContactPersonsToCompanyWithSuccess() {
        TblCompany company = MockDataHelper.mockCompany();
        company.setContactPersons( MockDataHelper.mockTblContactPersons());
        company.getContactPersons().get(1).getContact().setAnonymized(true);
        when(companyRepository.findByTblContactUuid(any(UUID.class))).thenReturn(Optional.of(company));
        List<ContactPersonDto> cpDtos = companyService.findContactPersonsToCompany(UUID.randomUUID(), true);
        assertEquals(company.getContactPersons().size(), cpDtos.size());
        assertEquals(company.getContactPersons().get(1).getContact().getUuid(), cpDtos.get(1).getContactUuid());

        List<ContactPersonDto> cpDtos2 = companyService.findContactPersonsToCompany(UUID.randomUUID(), false);
        assertNotEquals(cpDtos.size(), cpDtos2.size());
    }


    @Test
    void findContactPersonsToCompanyWithException() {
        when(companyRepository.findByTblContactUuid(any(UUID.class))).thenReturn(Optional.empty());
        assertThrows( NotFoundException.class, ()-> companyService.findContactPersonsToCompany(UUID.randomUUID(), false));
    }
}