/*
 *******************************************************************************
 * 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.RefAddressType;
import org.eclipse.openk.contactbasedata.model.TblAddress;
import org.eclipse.openk.contactbasedata.model.TblAssignmentModulContact;
import org.eclipse.openk.contactbasedata.model.TblContact;
import org.eclipse.openk.contactbasedata.repository.AddressRepository;
import org.eclipse.openk.contactbasedata.repository.AddressTypeRepository;
import org.eclipse.openk.contactbasedata.repository.AssignmentModulContactRepository;
import org.eclipse.openk.contactbasedata.repository.ContactRepository;
import org.eclipse.openk.contactbasedata.support.MockDataHelper;
import org.eclipse.openk.contactbasedata.viewmodel.AddressDto;
import org.eclipse.openk.contactbasedata.viewmodel.AssignmentModulContactDto;
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 AssignmentModulContactServiceTest {
    @Qualifier("myAssignmentModulContactService")
    @Autowired
    private AssignmentModulContactService assignmentService;

    @MockBean
    private AssignmentModulContactRepository assignmentRepository;

    @MockBean
    private ContactRepository contactRepository;


    @Test
    public void shouldReturnAssignmentsByContactUuid() {

        List<TblAssignmentModulContact> listTblAssignments = MockDataHelper.mockTblAssignmentsList();
        when(assignmentRepository.findByTblContactUuid( any(UUID.class)) ).thenReturn(listTblAssignments);

        List<AssignmentModulContactDto> tblAssignmentsList = assignmentService.getAssignments(UUID.randomUUID());
        assertEquals(tblAssignmentsList.size(), 2 );
    }

    @Test
    public void shouldUpdateAssignment() {
        TblAssignmentModulContact tblAssignment = MockDataHelper.mockTblAssignmentModulContact();
        AssignmentModulContactDto assignmentDto = MockDataHelper.mockAssignmentModulContactDto();
        TblContact tblContact = MockDataHelper.mockTblContact();
        tblAssignment.setTblContact(tblContact);

        when (contactRepository.findByUuid( any(UUID.class))).thenReturn(Optional.of(tblContact));
        when(assignmentRepository.findByUuid(any(UUID.class))).thenReturn(Optional.of(tblAssignment));
        when(assignmentRepository.save(any(TblAssignmentModulContact.class))).thenReturn(tblAssignment);
        when(assignmentRepository.countByContactIdAndUuidAndModulNameIsNotSame(anyLong(),any(UUID.class),anyString())).thenReturn(0L);

        AssignmentModulContactDto savedAssignment = assignmentService.updateAssignment(assignmentDto.getUuid(), assignmentDto);

        assertEquals(tblAssignment.getTblContact().getUuid(), savedAssignment.getContactUuid());
        assertEquals(tblAssignment.getUuid(), savedAssignment.getUuid());
        assertEquals(tblAssignment.getAssignmentDate(), savedAssignment.getAssignmentDate());
        assertEquals(tblAssignment.getAssignmentNote(), savedAssignment.getAssignmentNote());
        assertEquals(tblAssignment.getDeletionLockUntil(), savedAssignment.getDeletionLockUntil());
        assertEquals(tblAssignment.getExpiringDate(), savedAssignment.getExpiringDate());
        assertEquals(tblAssignment.getModulName(), savedAssignment.getModulName());
    }

    @Test
    public void shouldNotUpdateAssignment_Exception1() {
        TblAssignmentModulContact tblAssignment = MockDataHelper.mockTblAssignmentModulContact();
        AssignmentModulContactDto assignmentDto = MockDataHelper.mockAssignmentModulContactDto();
        TblContact tblContact = MockDataHelper.mockTblContact();
        tblAssignment.setTblContact(tblContact);

        when (contactRepository.findByUuid( any(UUID.class))).thenReturn(Optional.empty());
        when(assignmentRepository.findByUuid(any(UUID.class))).thenReturn(Optional.of(tblAssignment));
        when(assignmentRepository.save(any(TblAssignmentModulContact.class))).thenReturn(tblAssignment);
        when(assignmentRepository.countByContactIdAndUuidAndModulNameIsNotSame(anyLong(),any(UUID.class),anyString())).thenReturn(0L);

        assertThrows( NotFoundException.class, () -> assignmentService.updateAssignment(assignmentDto.getUuid(), assignmentDto));
    }

    @Test
    public void shouldNotUpdateAssignment_Exception2() {
        TblAssignmentModulContact tblAssignment = MockDataHelper.mockTblAssignmentModulContact();
        AssignmentModulContactDto assignmentDto = MockDataHelper.mockAssignmentModulContactDto();
        TblContact tblContact = MockDataHelper.mockTblContact();
        tblAssignment.setTblContact(tblContact);

        when (contactRepository.findByUuid( any(UUID.class))).thenReturn(Optional.of(tblContact));
        when(assignmentRepository.findByUuid(any(UUID.class))).thenReturn(Optional.empty());
        when(assignmentRepository.save(any(TblAssignmentModulContact.class))).thenReturn(tblAssignment);
        when(assignmentRepository.countByContactIdAndUuidAndModulNameIsNotSame(anyLong(),any(UUID.class),anyString())).thenReturn(0L);

        assertThrows( NotFoundException.class, () -> assignmentService.updateAssignment(assignmentDto.getUuid(), assignmentDto));
    }

    @Test
    public void shouldNotUpdateAssignment_Exception3() {
        TblAssignmentModulContact tblAssignment = MockDataHelper.mockTblAssignmentModulContact();
        AssignmentModulContactDto assignmentDto = MockDataHelper.mockAssignmentModulContactDto();
        TblContact tblContact = MockDataHelper.mockTblContact();
        tblAssignment.setTblContact(tblContact);

        when (contactRepository.findByUuid( any(UUID.class))).thenReturn(Optional.of(tblContact));
        when(assignmentRepository.findByUuid(any(UUID.class))).thenReturn(Optional.of(tblAssignment));
        when(assignmentRepository.save(any(TblAssignmentModulContact.class))).thenReturn(tblAssignment);
        when(assignmentRepository.countByContactIdAndUuidAndModulNameIsNotSame(anyLong(),any(UUID.class),anyString())).thenReturn(4L);

        assertThrows( OperationDeniedException.class, () -> assignmentService.updateAssignment(assignmentDto.getUuid(), assignmentDto));

    }

    @Test
    public void shouldInsertAssignment() {
        TblAssignmentModulContact tblAssignment = MockDataHelper.mockTblAssignmentModulContact();
        AssignmentModulContactDto assignmentDto = MockDataHelper.mockAssignmentModulContactDto();
        TblContact tblContact = MockDataHelper.mockTblContact();
        tblAssignment.setTblContact(tblContact);

        when (contactRepository.findByUuid( any(UUID.class))).thenReturn(Optional.of(tblContact));
        when(assignmentRepository.findByUuid(any(UUID.class))).thenReturn(Optional.of(tblAssignment));
        when(assignmentRepository.save(any(TblAssignmentModulContact.class))).thenReturn(tblAssignment);
        when(assignmentRepository.countByContactIdAndModuleName(anyLong(), anyString())).thenReturn(0L);

        AssignmentModulContactDto savedAssignment = assignmentService.insertAssignment(assignmentDto.getUuid(), assignmentDto);

        assertNotNull(savedAssignment.getContactUuid());
        assertEquals(tblAssignment.getTblContact().getUuid(), savedAssignment.getContactUuid());
        assertEquals(tblAssignment.getAssignmentDate(), savedAssignment.getAssignmentDate());
        assertEquals(tblAssignment.getAssignmentNote(), savedAssignment.getAssignmentNote());
        assertEquals(tblAssignment.getDeletionLockUntil(), savedAssignment.getDeletionLockUntil());
        assertEquals(tblAssignment.getExpiringDate(), savedAssignment.getExpiringDate());
        assertEquals(tblAssignment.getModulName(), savedAssignment.getModulName());

    }

    @Test
    public void shouldNotInsertAssignment_Exception_1() {
        TblAssignmentModulContact tblAssignment = MockDataHelper.mockTblAssignmentModulContact();
        AssignmentModulContactDto assignmentDto = MockDataHelper.mockAssignmentModulContactDto();
        TblContact tblContact = MockDataHelper.mockTblContact();
        tblAssignment.setTblContact(tblContact);

        when (contactRepository.findByUuid( any(UUID.class))).thenReturn(Optional.empty());
        when(assignmentRepository.findByUuid(any(UUID.class))).thenReturn(Optional.of(tblAssignment));
        when(assignmentRepository.save(any(TblAssignmentModulContact.class))).thenReturn(tblAssignment);
        when(assignmentRepository.countByContactIdAndModuleName(anyLong(), anyString())).thenReturn(0L);

        assertThrows( NotFoundException.class, () -> assignmentService.insertAssignment(assignmentDto.getUuid(), assignmentDto));

    }


    @Test
    public void shouldNotInsertAssignment_Exception_2() {
        TblAssignmentModulContact tblAssignment = MockDataHelper.mockTblAssignmentModulContact();
        AssignmentModulContactDto assignmentDto = MockDataHelper.mockAssignmentModulContactDto();
        TblContact tblContact = MockDataHelper.mockTblContact();
        tblAssignment.setTblContact(tblContact);

        when (contactRepository.findByUuid( any(UUID.class))).thenReturn(Optional.of(tblContact));
        when(assignmentRepository.countByContactIdAndModuleName(anyLong(), anyString())).thenReturn(2L);
        when(assignmentRepository.save(any(TblAssignmentModulContact.class))).thenReturn(tblAssignment);

        assertThrows( OperationDeniedException.class, () -> assignmentService.insertAssignment(assignmentDto.getUuid(), assignmentDto));

    }


    @Test
    public void shouldDeleteAssignment() {
        TblAssignmentModulContact tblAssignment = MockDataHelper.mockTblAssignmentModulContact();
        TblContact tblContact = MockDataHelper.mockTblContact();
        tblAssignment.setTblContact(tblContact);

        when (contactRepository.findByUuid( any(UUID.class))).thenReturn(Optional.of(tblContact));
        when(assignmentRepository.findByTblContactAndUuid(any(TblContact.class), any(UUID.class))).thenReturn(Optional.of(tblAssignment));
        Mockito.doNothing().when(assignmentRepository).delete( isA( TblAssignmentModulContact.class ));

        assignmentService.deleteAssignment(tblContact.getUuid(), tblAssignment.getUuid());

        Mockito.verify(assignmentRepository, times(1)).delete( tblAssignment );
    }

}
