/*
 *******************************************************************************
 * 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.exceptions.OperationDeniedException;
import org.eclipse.openk.contactbasedata.model.*;
import org.eclipse.openk.contactbasedata.repository.*;
import org.eclipse.openk.contactbasedata.support.MockDataHelper;
import org.eclipse.openk.contactbasedata.viewmodel.CommunicationDto;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
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.test.context.ContextConfiguration;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import static org.hibernate.validator.internal.util.Contracts.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.when;

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

public class CommunicationServiceTest {
    @Qualifier("myCommunicationService")
    @Autowired
    private CommunicationService communicationService;

    @MockBean
    private CommunicationRepository communicationRepository;

    @MockBean
    private ContactRepository contactRepository;

    @MockBean
    private CommunicationTypeRepository communicationTypeRepository;

    @Test
    public void shouldReturnAddressesByContactUuid() {

        List<TblCommunication> listTblCommunications = MockDataHelper.mockTblCommunicationsList();
        when(communicationRepository.findByTblContactUuid( any(UUID.class)) ).thenReturn(listTblCommunications);

        List<CommunicationDto> dtoList = communicationService.getCommunicationsByContactUuid(UUID.randomUUID());
        assertEquals(dtoList.size(), 2 );
    }

    @Test
    public void shouldReturnCommunicationsByContactUuidAndCommunicationUuid() {

        TblCommunication tblCommunication = MockDataHelper.mockTblCommunication();
        when(communicationRepository.findByUuid( any(UUID.class)) ).thenReturn(Optional.of(tblCommunication));

       CommunicationDto dto = communicationService.getCommunication(tblCommunication.getTblContact().getUuid(), UUID.randomUUID());
        assertEquals(tblCommunication.getUuid(), dto.getUuid() );
    }

    @Test
    public void shouldUpdateCommunication() {
        CommunicationDto communicationDto = MockDataHelper.mockCommunicationDto();
        TblCommunication tblCommunication = MockDataHelper.mockTblCommunication();
        TblContact tblContact = MockDataHelper.mockTblContact();
        RefCommunicationType refCommunicationType = MockDataHelper.mockRefCommunicationType();
        tblCommunication.setTblContact(tblContact);

        when (contactRepository.findByUuid( any(UUID.class))).thenReturn(Optional.of(tblContact));
        when(communicationRepository.findByUuid(any(UUID.class))).thenReturn(Optional.of(tblCommunication));
        when(communicationRepository.save(any(TblCommunication.class))).thenReturn(tblCommunication);
        when (communicationTypeRepository.findByUuid(any(UUID.class))).thenReturn(Optional.of(refCommunicationType));

        CommunicationDto savedCommunication = communicationService.updateCommunication(communicationDto.getUuid(), communicationDto);

        assertEquals(tblCommunication.getTblContact().getUuid(), savedCommunication.getContactUuid());
        assertEquals(tblCommunication.getUuid(), savedCommunication.getUuid());
        assertEquals(tblCommunication.getRefCommunicationType().getUuid(), savedCommunication.getCommunicationTypeUuid());
        assertEquals(tblCommunication.getCommunicationData(), savedCommunication.getCommunicationData());

    }

    @Test
    public void shouldNotUpdateCommunication_Exception1() {
        CommunicationDto communicationDto = MockDataHelper.mockCommunicationDto();
        TblCommunication tblCommunication = MockDataHelper.mockTblCommunication();
        TblContact tblContact = MockDataHelper.mockTblContact();
        RefCommunicationType refCommunicationType = MockDataHelper.mockRefCommunicationType();
        tblCommunication.setTblContact(tblContact);

        when (contactRepository.findByUuid( any(UUID.class))).thenReturn(Optional.empty());
        when(communicationRepository.findByUuid(any(UUID.class))).thenReturn(Optional.of(tblCommunication));
        when (communicationTypeRepository.findByUuid(any(UUID.class))).thenReturn(Optional.of(refCommunicationType));
        when(communicationRepository.save(any(TblCommunication.class)))
                .then((Answer<TblCommunication>) invocation -> {
                    Object[] args = invocation.getArguments();
                    return (TblCommunication) args[0];
                });

        assertThrows( NotFoundException.class, () -> communicationService.updateCommunication(communicationDto.getUuid(), communicationDto));
    }

    @Test
    public void shouldNotUpdateCommunication_Exception2() {
        CommunicationDto communicationDto = MockDataHelper.mockCommunicationDto();
        TblCommunication tblCommunication = MockDataHelper.mockTblCommunication();
        TblContact tblContact = MockDataHelper.mockTblContact();

        tblCommunication.setTblContact(tblContact);


        when (contactRepository.findByUuid( any(UUID.class))).thenReturn(Optional.of(tblContact));
        when(communicationRepository.findByUuid(any(UUID.class))).thenReturn(Optional.of(tblCommunication));
        when (communicationRepository.findByUuid(any(UUID.class))).thenReturn(Optional.empty());
        when(communicationRepository.save(any(TblCommunication.class)))
                .then((Answer<TblAddress>) invocation -> {
                    Object[] args = invocation.getArguments();
                    return (TblAddress) args[0];
                });

        assertThrows( NotFoundException.class, () -> communicationService.updateCommunication(communicationDto.getUuid(), communicationDto));
    }

    @Test
    public void shouldNotUpdateCommunication_Exception3() {
        CommunicationDto communicationDto = MockDataHelper.mockCommunicationDto();
        TblCommunication tblCommunication = MockDataHelper.mockTblCommunication();
        TblContact tblContact = MockDataHelper.mockTblContact();
        RefCommunicationType refCommunicationType = MockDataHelper.mockRefCommunicationType();
        tblCommunication.setTblContact(tblContact);

        when (contactRepository.findByUuid( any(UUID.class))).thenReturn(Optional.of(tblContact));
        when(communicationRepository.findByUuid(any(UUID.class))).thenReturn(Optional.of(tblCommunication));
        when(communicationRepository.countByContactIdAndCommunicationTypeIdAndIsNotSame(any(Long.class), any(Long.class), any(UUID.class)) ).thenReturn(3L);
        when (communicationTypeRepository.findByUuid(any(UUID.class))).thenReturn(Optional.of(refCommunicationType));

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

        assertThrows( OperationDeniedException.class, () -> communicationService.updateCommunication(communicationDto.getUuid(), communicationDto));

    }

    @Test
    public void shouldInsertCommunication() {
        CommunicationDto communicationDto = MockDataHelper.mockCommunicationDto();
        TblCommunication tblCommunication = MockDataHelper.mockTblCommunication();
        TblContact tblContact = MockDataHelper.mockTblContact();
        RefCommunicationType refCommunicationType = MockDataHelper.mockRefCommunicationType();
        tblCommunication.setTblContact(tblContact);

        when (contactRepository.findByUuid( any(UUID.class))).thenReturn(Optional.of(tblContact));
        when(communicationRepository.save(any(TblCommunication.class))).thenReturn(tblCommunication);
        when (communicationTypeRepository.findByUuid(any(UUID.class))).thenReturn(Optional.of(refCommunicationType));

        CommunicationDto savedCommunication = communicationService.insertCommunication(communicationDto.getUuid(), communicationDto);

        assertNotNull(savedCommunication.getContactUuid());
        assertEquals(tblCommunication.getTblContact().getUuid(), savedCommunication.getContactUuid());
        assertEquals(tblCommunication.getUuid(), savedCommunication.getUuid());
        assertEquals(tblCommunication.getCommunicationData(), savedCommunication.getCommunicationData());
        assertEquals(tblCommunication.getRefCommunicationType().getUuid(), savedCommunication.getCommunicationTypeUuid());
    }

    @Test
    public void shouldNotInsertCommunication_Exception_1() {
        CommunicationDto communicationDto = MockDataHelper.mockCommunicationDto();
        TblCommunication tblCommunication = MockDataHelper.mockTblCommunication();
        TblContact tblContact = MockDataHelper.mockTblContact();
        RefCommunicationType refCommunicationType = MockDataHelper.mockRefCommunicationType();
        tblCommunication.setTblContact(tblContact);

        when (contactRepository.findByUuid( any(UUID.class))).thenReturn(Optional.empty());
        when(communicationRepository.save(any(TblCommunication.class))).thenReturn(tblCommunication);
        when (communicationTypeRepository.findByUuid(any(UUID.class))).thenReturn(Optional.of(refCommunicationType));

        assertThrows( NotFoundException.class, () -> communicationService.insertCommunication(communicationDto.getUuid(), communicationDto));

    }

    @Test
    public void shouldNotInsertCommunication_Exception_2() {
        CommunicationDto communicationDto = MockDataHelper.mockCommunicationDto();
        TblCommunication tblCommunication = MockDataHelper.mockTblCommunication();
        TblContact tblContact = MockDataHelper.mockTblContact();
        tblCommunication.setTblContact(tblContact);

        when (contactRepository.findByUuid( any(UUID.class))).thenReturn(Optional.of(tblContact));
        when(communicationRepository.save(any(TblCommunication.class))).thenReturn(tblCommunication);
        when (communicationTypeRepository.findByUuid(any(UUID.class))).thenReturn(Optional.empty());

        assertThrows( NotFoundException.class, () -> communicationService.insertCommunication(communicationDto.getUuid(), communicationDto));

    }


    @Test
    public void shouldNotInsertCommunication_Exception3() {
        CommunicationDto communicationDto = MockDataHelper.mockCommunicationDto();
        TblCommunication tblCommunication = MockDataHelper.mockTblCommunication();
        RefCommunicationType refCommunicationType = MockDataHelper.mockRefCommunicationType();
        TblContact tblContact = MockDataHelper.mockTblContact();
        tblCommunication.setTblContact(tblContact);

        when (contactRepository.findByUuid( any(UUID.class))).thenReturn(Optional.of(tblContact));
        when (communicationTypeRepository.findByUuid(any(UUID.class))).thenReturn(Optional.of(refCommunicationType));
        when(communicationRepository.countByContactIdAndCommunicationTypeId(anyLong(), anyLong())).thenReturn(2L);
        when(communicationRepository.save(any(TblCommunication.class))).thenReturn(tblCommunication);

        assertThrows( OperationDeniedException.class, () -> communicationService.insertCommunication(communicationDto.getUuid(), communicationDto));

    }


    @Test
    public void shouldDeleteCommunication() {
        TblCommunication tblCommunication = MockDataHelper.mockTblCommunication();
        TblContact tblContact = MockDataHelper.mockTblContact();
        tblCommunication.setTblContact(tblContact);

        when (contactRepository.findByUuid( any(UUID.class))).thenReturn(Optional.of(tblContact));
        when(communicationRepository.findByTblContactAndUuid(any(TblContact.class), any(UUID.class))).thenReturn(Optional.of(tblCommunication));
        Mockito.doNothing().when(communicationRepository).delete( isA( TblCommunication.class ));

        communicationService.deleteCommunication(tblContact.getUuid(), tblCommunication.getUuid());

        Mockito.verify(communicationRepository, times(1)).delete( tblCommunication );
    }

}
