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

}
