/*
 *******************************************************************************
 * 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.assertj.core.util.Lists;
import org.eclipse.openk.contactbasedata.config.TestConfiguration;
import org.eclipse.openk.contactbasedata.model.RefCommunicationType;
import org.eclipse.openk.contactbasedata.model.TblInternalPerson;
import org.eclipse.openk.contactbasedata.repository.CommunicationTypeRepository;
import org.eclipse.openk.contactbasedata.repository.InternalPersonRepository;
import org.eclipse.openk.contactbasedata.service.util.LdapUserAttributesMapper;
import org.eclipse.openk.contactbasedata.support.MockDataHelper;
import org.eclipse.openk.contactbasedata.viewmodel.LdapUser;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.mockito.stubbing.Answer;
import org.powermock.reflect.Whitebox;
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.ldap.core.LdapTemplate;
import org.springframework.ldap.query.LdapQuery;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;

import java.util.ArrayList;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.when;

@DataJpaTest
@ContextConfiguration(classes = {TestConfiguration.class})
@ActiveProfiles("test")
class LdapServiceTest {
    private static final long MAIL_ID = 1L;
    private static final long TEL_ID = 2L;

    @Qualifier("myLdapService")
    @Autowired
    private LdapService ldapService;

    @Autowired
    private LdapUserAttributesMapper ldapUserAttributesMapper;

    @MockBean
    private InternalPersonService internalPersonService;

    @MockBean
    private InternalPersonRepository internalPersonRepository;

    @MockBean
    private CommunicationTypeRepository communicationTypeRepository;

    @Autowired
    private LdapTemplate ldapTemplate;

    @Test
    void shouldSynchronizeLDAPRunThrou1() {
        when(internalPersonRepository.saveAll(any( List.class ))).thenReturn(Lists.emptyList());
        List<TblInternalPerson> internalPeople = MockDataHelper.mockTblInternalPersonPage().getContent();
        when( internalPersonRepository.findByUidIdentNotNull() ).thenReturn(internalPeople);

        List<LdapUser> ldapUserList = new ArrayList<>(1);
        LdapUser ldapUser = MockDataHelper.mockLdapUser();
        ldapUser.setUid(internalPeople.get(0).getUidIdent());
        ldapUserList.add( ldapUser );
        // users are found
        when( ldapTemplate.search(any(LdapQuery.class), any(LdapUserAttributesMapper.class))).thenReturn( ldapUserList );

        List<RefCommunicationType> refCommunicationTypes = MockDataHelper.mockRefCommunicationTypeList();
        Whitebox.setInternalState(ldapService, "mailId", MAIL_ID);
        Whitebox.setInternalState(ldapService, "telephoneNumberId", TEL_ID);
        refCommunicationTypes.get(1).setId(TEL_ID);
        refCommunicationTypes.get(2).setId(MAIL_ID);
        when( communicationTypeRepository.findAll()).thenReturn(refCommunicationTypes);

        when(internalPersonRepository.saveAll(any( List.class)))
                .then((Answer<List<TblInternalPerson>>) invocation -> {
                    Object[] args = invocation.getArguments();
                    return (List<TblInternalPerson>) args[0];
                });


        ldapService.synchronizeLDAP();
        Mockito.verify(internalPersonRepository, times(2)).saveAll(any(List.class));
    }

    @Test
    void shouldSynchronizeLDAPRunThrou2() {

        when(internalPersonRepository.saveAll(any( List.class ))).thenReturn(Lists.emptyList());
        List<TblInternalPerson> internalPeople = MockDataHelper.mockTblInternalPersonPage().getContent();
        when( internalPersonRepository.findByUidIdentNotNull() ).thenReturn(internalPeople);

        // users are not found
        when( ldapTemplate.search(any(LdapQuery.class), any(LdapUserAttributesMapper.class))).thenReturn( Lists.emptyList() );

        List<RefCommunicationType> refCommunicationTypes = MockDataHelper.mockRefCommunicationTypeList();
        Whitebox.setInternalState(ldapService, "mailId", MAIL_ID);
        Whitebox.setInternalState(ldapService, "telephoneNumberId", TEL_ID);
        refCommunicationTypes.get(1).setId(TEL_ID);
        refCommunicationTypes.get(2).setId(MAIL_ID);
        when( communicationTypeRepository.findAll()).thenReturn(refCommunicationTypes);

        ldapService.synchronizeLDAP();
        Mockito.verify(internalPersonRepository, times(2)).saveAll(any(List.class));

    }

    @Test
    void shouldFindExistingAndNotExistingLdapUsers1() throws Exception {
        List<TblInternalPerson> internalPeople = MockDataHelper.mockTblInternalPersonPage().getContent();
        List<LdapUser> ldapUsers = new ArrayList<>();
        List<TblInternalPerson> allNotExistingLdapUsers = new ArrayList<>();

        List<LdapUser> ldapUserList = new ArrayList<>(1);
        LdapUser ldapUser = MockDataHelper.mockLdapUser();
        ldapUser.setUid(internalPeople.get(0).getUidIdent());
        ldapUserList.add( ldapUser );
        // users are always found
        when( ldapTemplate.search(any(LdapQuery.class), any(LdapUserAttributesMapper.class))).thenReturn( ldapUserList );

        Whitebox.invokeMethod(ldapService, "findExistingAndNotExistingLdapUsers",
                internalPeople, ldapUsers, allNotExistingLdapUsers);

        assertEquals( internalPeople.size(), ldapUsers.size());
        assertEquals( ldapUser, ldapUsers.get(0));
        assertEquals( ldapUser, ldapUsers.get(1));
    }

    @Test
    void shouldFindExistingAndNotExistingLdapUsers2() throws Exception {
        List<TblInternalPerson> internalPeople = MockDataHelper.mockTblInternalPersonPage().getContent();
        List<LdapUser> ldapUsers = new ArrayList<>();
        List<TblInternalPerson> allNotExistingLdapUsers = new ArrayList<>();

        // users are not found
        when( ldapTemplate.search(any(LdapQuery.class), any(LdapUserAttributesMapper.class))).thenReturn( Lists.emptyList() );

        Whitebox.invokeMethod(ldapService, "findExistingAndNotExistingLdapUsers",
                internalPeople, ldapUsers, allNotExistingLdapUsers);

        assertEquals( 0, ldapUsers.size());
    }


    @Test
    void shouldFindExistingAndNotExistingLdapUsers3() throws Exception {
        List<TblInternalPerson> internalPeople = MockDataHelper.mockTblInternalPersonPage().getContent();
        List<LdapUser> ldapUsers = new ArrayList<>();
        List<TblInternalPerson> allNotExistingLdapUsers = new ArrayList<>();

        List<LdapUser> ldapUserList = new ArrayList<>(1);
        LdapUser ldapUser = MockDataHelper.mockLdapUser();
        ldapUser.setUid(internalPeople.get(0).getUidIdent());
        ldapUserList.add( ldapUser );
        ldapUserList.add( new LdapUser());
        // too much users are found
        when( ldapTemplate.search(any(LdapQuery.class), any(LdapUserAttributesMapper.class))).thenReturn( ldapUserList );

        Whitebox.invokeMethod(ldapService, "findExistingAndNotExistingLdapUsers",
                internalPeople, ldapUsers, allNotExistingLdapUsers);

        assertEquals( 0, ldapUsers.size());
    }

}
