/*
 *******************************************************************************
 * 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.TblAssignmentModulContact;
import org.eclipse.openk.contactbasedata.model.TblContact;
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.AssignmentModulContactDto;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
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.ActiveProfiles;
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.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.when;

@DataJpaTest
@ContextConfiguration(classes = {TestConfiguration.class})
@ActiveProfiles("test")
class AssignmentModulContactServiceTest {
    @Qualifier("myAssignmentModulContactService")
    @Autowired
    private AssignmentModulContactService assignmentService;

    @MockBean
    private AssignmentModulContactRepository assignmentRepository;

    @MockBean
    private ContactRepository contactRepository;


    @Test
    void shouldReturnAssignmentsByContactUuid() {

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

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


    @Test
    void shouldReturnSingleAssignmentsByContactUuidAndAssignUuid() {
        TblAssignmentModulContact tblAssignment = MockDataHelper.mockTblAssignmentModulContact();
        when(assignmentRepository.findByUuid(any(UUID.class)) ).thenReturn(Optional.of(tblAssignment));

        AssignmentModulContactDto assignmentDto = assignmentService.getAssignment(
                tblAssignment.getTblContact().getUuid(), UUID.randomUUID());
        assertEquals(assignmentDto.getContactUuid(), tblAssignment.getTblContact().getUuid() );

        // try it with a not matching contactUUID
        assertThrows(NotFoundException.class, () -> assignmentService.getAssignment(UUID.randomUUID(), UUID.randomUUID()));

        // try it with an empty repository result
        when(assignmentRepository.findByUuid(any(UUID.class))).thenReturn(Optional.empty());
        assertThrows(NotFoundException.class, () ->
                assignmentService.getAssignment(assignmentDto.getContactUuid(), UUID.randomUUID()));
    }
    @Test
    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
    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
    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
    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
    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
    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
    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
    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 );
    }

}
