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

public 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
    public void shouldSynchronizeLDAPRunThrou1() {
        when(internalPersonRepository.saveAll(any( List.class ))).thenReturn(Lists.emptyList());
        List<TblInternalPerson> internalPeople = MockDataHelper.mockTblInternalPersonPage().getContent();
        when( internalPersonRepository.findByUidNotNull() ).thenReturn(internalPeople);

        List<LdapUser> ldapUserList = new ArrayList<>(1);
        LdapUser ldapUser = MockDataHelper.mockLdapUser();
        ldapUser.setUid(internalPeople.get(0).getUid());
        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
    public void shouldSynchronizeLDAPRunThrou2() {

        when(internalPersonRepository.saveAll(any( List.class ))).thenReturn(Lists.emptyList());
        List<TblInternalPerson> internalPeople = MockDataHelper.mockTblInternalPersonPage().getContent();
        when( internalPersonRepository.findByUidNotNull() ).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
    public 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).getUid());
        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
    public 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
    public 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).getUid());
        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());
    }

}
