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

import org.eclipse.openk.contactbasedata.constants.Constants;
import org.eclipse.openk.contactbasedata.model.KeyCloakUser;
import org.eclipse.openk.contactbasedata.model.RefAddressType;
import org.eclipse.openk.contactbasedata.model.RefCommunicationType;
import org.eclipse.openk.contactbasedata.model.RefPersonType;
import org.eclipse.openk.contactbasedata.model.RefSalutation;
import org.eclipse.openk.contactbasedata.model.TblAddress;
import org.eclipse.openk.contactbasedata.model.TblAssignmentModulContact;
import org.eclipse.openk.contactbasedata.model.TblCommunication;
import org.eclipse.openk.contactbasedata.model.TblCompany;
import org.eclipse.openk.contactbasedata.model.TblContact;
import org.eclipse.openk.contactbasedata.model.TblContactPerson;
import org.eclipse.openk.contactbasedata.model.TblExternalPerson;
import org.eclipse.openk.contactbasedata.model.TblInternalPerson;
import org.eclipse.openk.contactbasedata.model.Version;
import org.eclipse.openk.contactbasedata.model.VwDetailedContact;
import org.eclipse.openk.contactbasedata.viewmodel.AddressDto;
import org.eclipse.openk.contactbasedata.viewmodel.AddressTypeDto;
import org.eclipse.openk.contactbasedata.viewmodel.AssignmentModulContactDto;
import org.eclipse.openk.contactbasedata.viewmodel.CommunicationDto;
import org.eclipse.openk.contactbasedata.viewmodel.CommunicationTypeDto;
import org.eclipse.openk.contactbasedata.viewmodel.CompanyDto;
import org.eclipse.openk.contactbasedata.viewmodel.ContactDto;
import org.eclipse.openk.contactbasedata.viewmodel.ContactPersonDto;
import org.eclipse.openk.contactbasedata.viewmodel.ExternalPersonDto;
import org.eclipse.openk.contactbasedata.viewmodel.InternalPersonDto;
import org.eclipse.openk.contactbasedata.viewmodel.LdapUser;
import org.eclipse.openk.contactbasedata.viewmodel.PersonTypeDto;
import org.eclipse.openk.contactbasedata.viewmodel.SalutationDto;
import org.eclipse.openk.contactbasedata.viewmodel.VersionDto;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;

import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import java.sql.Date;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class MockDataHelper {

    public static Version mockVersion() {
        Version version = new Version();
        version.setId(4711L);
        version.setVersion("db-version_mock_1");
        return version;
    }

    public static VersionDto mockVersionDto() {
        VersionDto versionDto = new VersionDto();
        versionDto.setBackendVersion("660");
        versionDto.setDbVersion("550");
        return versionDto;
    }

    public static VwDetailedContact mockVDetailedContact() {
        VwDetailedContact contact = new VwDetailedContact();
        contact.setId(1L);
        contact.setUuid(UUID.randomUUID());
        contact.setName("Haferkamp");
        return contact;
    }

    public static Page<VwDetailedContact> mockVDetailedContactPage() {
        VwDetailedContact v1 = mockVDetailedContact();
        VwDetailedContact v2 = mockVDetailedContact();
        v2.setId(2L);
        v2.setName("Strofanov");
        List<VwDetailedContact> list = Arrays.asList(v1, v2);
        return new PageImpl<>(list, Pageable.unpaged(), list.size());
    }

    public static TblExternalPerson mockExternalPerson() {
        TblContact c = new TblContact();
        c.setId( 3L );
        c.setContactType(Constants.CONTACT_TYPE_EXTERNAL_PERSON);
        c.setUuid(UUID.randomUUID());
        TblExternalPerson e = new TblExternalPerson();
        e.setId( 34L );
        e.setContact(c);
        e.setFirstName("Florinda");
        e.setLastName("Fieselbrink");
        e.setTitle("Dr. von und zu");
        e.setRefPersonType(mockRefPersonType());
        e.setSalutation(mockRefSalutation());
        c.setNote("Notiz am Rande");
        return e;
    }

    public static ExternalPersonDto mockExternalPersonDto() {
        ExternalPersonDto epd = new ExternalPersonDto();
        epd.setContactUuid(UUID.randomUUID());
        epd.setFirstName("Zotto");
        epd.setLastName("Briketti");
        epd.setContactType(Constants.CONTACT_TYPE_EXTERNAL_PERSON);
        epd.setTitle("Dr. von und zu");
        epd.setPersonTypeUuid(UUID.randomUUID());
        epd.setSalutationUuid(UUID.randomUUID());
        epd.setContactNote("Notiz am Rande");
        return epd;
    }

    public static Page<TblExternalPerson> mockExternalPersonPage() {
        TblExternalPerson ep1 = mockExternalPerson();
        TblExternalPerson ep2 = mockExternalPerson();
        ep2.setFirstName("Strofanov");
        ep2.getContact().setUuid(UUID.randomUUID());
        List<TblExternalPerson> list = Arrays.asList(ep1, ep2);
        return new PageImpl<>(list, Pageable.unpaged(), list.size());
    }

    public static Page<ExternalPersonDto> mockExternalPersonDtoPage() {
        ExternalPersonDto ep1 = mockExternalPersonDto();
        ExternalPersonDto ep2 = mockExternalPersonDto();
        ep2.setFirstName("Strofanov");
        ep2.setContactUuid(UUID.randomUUID());
        List<ExternalPersonDto> list = Arrays.asList(ep1, ep2);
        return new PageImpl<>(list, Pageable.unpaged(), list.size());
    }
    public static RefSalutation mockRefSalutation() {
        RefSalutation sal = new RefSalutation();
        sal.setId(1L);
        sal.setUuid(UUID.randomUUID());
        sal.setDescription("Ave Marcus Antonius");
        sal.setType("Maitre");
        return sal;
    }

    public static SalutationDto mockSalutationDto() {
        SalutationDto sal = new SalutationDto();
        sal.setUuid(UUID.randomUUID());
        sal.setDescription("Ave Caesar");
        sal.setType("Maitre");
        return sal;
    }

    public static List<SalutationDto> mockSalutationsDtos() {
        List<SalutationDto> dtos = new LinkedList<>();
        dtos.add( mockSalutationDto() );
        SalutationDto sd2 = mockSalutationDto();
        sd2.setType("Magistra");
        sd2.setDescription("Ave Cleopatra");
        dtos.add( sd2 );
        return dtos;
    }

    public static List<RefSalutation> mockRefSalutations() {
        List<RefSalutation> refs = new LinkedList<>();
        refs.add( mockRefSalutation() );
        RefSalutation sd2 = mockRefSalutation();
        sd2.setType("Magistra");
        sd2.setDescription("Ave Messalina");
        refs.add( sd2 );
        return refs;
    }

    public static RefPersonType mockRefPersonType() {
        RefPersonType refPersonType = new RefPersonType();
        refPersonType.setId(1L);
        refPersonType.setUuid(UUID.randomUUID());
        refPersonType.setDescription("Ehrenmann");
        refPersonType.setType("ElCapitan");
        return refPersonType;
    }

    public static PersonTypeDto mockPersonTypeDto() {
        PersonTypeDto personTypeDto = new PersonTypeDto();
        personTypeDto.setUuid(UUID.randomUUID());
        personTypeDto.setDescription("Ehrenmann");
        personTypeDto.setType("ElCapitan");
        return personTypeDto;
    }

    public static List<PersonTypeDto> mockPersonTypesDtos() {
        List<PersonTypeDto> dtos = new LinkedList<>();
        dtos.add( mockPersonTypeDto() );
        PersonTypeDto sd2 = mockPersonTypeDto();
        sd2.setType("Gutmensch");
        sd2.setDescription("Zu guter Mensch");
        dtos.add( sd2 );
        return dtos;
    }

    public static List<RefPersonType> mockRefPersonTypes() {
        List<RefPersonType> refs = new LinkedList<>();
        refs.add( mockRefPersonType() );
        RefPersonType sd2 = mockRefPersonType();
        sd2.setType("Gutmensch");
        sd2.setDescription("Zu guter Mensch");
        refs.add( sd2 );
        return refs;
    }

    public static RefAddressType mockRefAddressType() {
        RefAddressType refAddressType = new RefAddressType();
        refAddressType.setId(1L);
        refAddressType.setUuid(UUID.randomUUID());
        refAddressType.setDescription("Zweitwohnsitz");
        refAddressType.setType("Nebenadresse");
        return refAddressType;
    }

    public static AddressTypeDto mockAddressTypeDto() {
        AddressTypeDto addressTypeDto = new AddressTypeDto();
        addressTypeDto.setUuid(UUID.randomUUID());
        addressTypeDto.setDescription("Zweitwohnsitz");
        addressTypeDto.setType("Nebenadresse");
        return addressTypeDto;
    }

    public static List<AddressTypeDto> mockAddressTypesDtos() {
        List<AddressTypeDto> dtos = new LinkedList<>();
        dtos.add( mockAddressTypeDto() );
        AddressTypeDto sd2 = mockAddressTypeDto();
        sd2.setType("Mülltonne");
        sd2.setDescription("Drittwohnsitz");
        dtos.add( sd2 );
        return dtos;
    }

    public static List<RefAddressType> mockRefAddressTypes() {
        List<RefAddressType> refs = new LinkedList<>();
        refs.add( mockRefAddressType() );
        RefAddressType sd2 = mockRefAddressType();
        sd2.setType("Mülltonne");
        sd2.setDescription("Drittwohnsitz");
        refs.add( sd2 );
        return refs;
    }

    public static TblAddress mockTblAddress(){
        TblAddress tblAddress = new TblAddress();

        tblAddress.setCommunity("Fischland");
        tblAddress.setCommunitySuffix("-");
        tblAddress.setHousenumber("13");
        tblAddress.setId(5L);
        tblAddress.setIsMainAddress(false);
        tblAddress.setLatitude("52N");
        tblAddress.setLongitude("2E");
        tblAddress.setNote("-");
        tblAddress.setPostcode("67890");
        tblAddress.setRefAddressType(mockRefAddressType());
        tblAddress.setStreet("Moosrosenweg");
        tblAddress.setTblContact(mockTblContact());
        tblAddress.setUrlMap("-");
        tblAddress.setUuid(UUID.fromString("f34dfffc-314a-11ea-978f-2e728ce88125"));
        tblAddress.setWgs_84_zone("-");

        return tblAddress;
    }

    public static AddressDto mockAddressDto(){
        AddressDto addressDto = new AddressDto();

        addressDto.setCommunity("Fischland");
        addressDto.setCommunitySuffix("-");
        addressDto.setHousenumber("13");
        addressDto.setIsMainAddress(false);
        addressDto.setLatitude("52N");
        addressDto.setLongitude("2E");
        addressDto.setNote("-");
        addressDto.setPostcode("67890");
        addressDto.setAddressTypeUuid(mockRefAddressType().getUuid());
        addressDto.setStreet("Moosrosenweg");
        addressDto.setContactUuid(UUID.randomUUID());
        addressDto.setUrlMap("-");
        addressDto.setUuid(UUID.fromString("f34dfffc-314a-11ea-978f-2e728ce88125"));
        addressDto.setWgs84Zone("-");

        addressDto.setContactUuid(UUID.randomUUID());

        return addressDto;
    }

    public static List<AddressDto> mockAddressDtoList(){

        List<AddressDto> list = new ArrayList<>();

        AddressDto addressDto1 = mockAddressDto();

        AddressDto addressDto2 = new AddressDto();
        addressDto2.setCommunity("Pusemuckel");
        addressDto2.setCommunitySuffix("-");
        addressDto2.setHousenumber("17");
        addressDto2.setIsMainAddress(false);
        addressDto2.setLatitude("51N");
        addressDto2.setLongitude("3E");
        addressDto2.setNote("-");
        addressDto2.setPostcode("87655");
        //addressDto.setRefAddressType();
        addressDto2.setStreet("Birkenweg");
        //addressDto.setTblContact();
        addressDto2.setUrlMap("-");
        addressDto2.setUuid(UUID.fromString("7dff534c-314d-11ea-978f-2e728ce88125"));
        addressDto2.setWgs84Zone("-");

        list.add(addressDto1);
        list.add(addressDto2);

        return list;
    }

    public static List<TblAddress> mockTblAddressList(){

        List<TblAddress> list = new ArrayList<>();

        TblAddress tblAddressDto1 = mockTblAddress();

        TblAddress tblAddressDto2 = new TblAddress();
        tblAddressDto2.setCommunity("Pusemuckel");
        tblAddressDto2.setCommunitySuffix("-");
        tblAddressDto2.setHousenumber("17");
        tblAddressDto2.setIsMainAddress(false);
        tblAddressDto2.setLatitude("51N");
        tblAddressDto2.setLongitude("3E");
        tblAddressDto2.setNote("-");
        tblAddressDto2.setPostcode("87655");
        tblAddressDto2.setRefAddressType(mockRefAddressType());
        tblAddressDto2.setStreet("Birkenweg");
        //tblAddressDto2.setTblContact();
        tblAddressDto2.setUrlMap("-");
        tblAddressDto2.setUuid(UUID.fromString("7dff534c-314d-11ea-978f-2e728ce88125"));
        tblAddressDto2.setWgs_84_zone("-");

        list.add(tblAddressDto1);
        list.add(tblAddressDto2);

        return list;
    }

    public static RefCommunicationType mockRefCommunicationType(){
        RefCommunicationType communicationType = new RefCommunicationType();
        communicationType.setId(2L);
        communicationType.setUuid(UUID.randomUUID());
        communicationType.setDescription("Fax");
        communicationType.setType("Fax");

        return communicationType;
    }

    public static CommunicationTypeDto mockCommunicationTypeDto(){
        CommunicationTypeDto communicationTypeDto = new CommunicationTypeDto();
        communicationTypeDto.setUuid(UUID.randomUUID());
        communicationTypeDto.setDescription("Fax");
        communicationTypeDto.setType("Fax");
        communicationTypeDto.setEditable(true);
        communicationTypeDto.setMappingLdap(false);

        return communicationTypeDto;
    }

    public static List<CommunicationTypeDto> mockCommunicationTypeDtoList(){

        CommunicationTypeDto ctDto1 = mockCommunicationTypeDto();
        CommunicationTypeDto ctDto2 = mockCommunicationTypeDto();
        ctDto2.setDescription("Mobil");
        ctDto2.setType("Mobil");
        CommunicationTypeDto ctDto3 = mockCommunicationTypeDto();
        ctDto3.setDescription("Pers�nlich");
        ctDto3.setType("Pers�nlich");

        List<CommunicationTypeDto> listCtDto = new ArrayList<>();
        listCtDto.add(ctDto1);
        listCtDto.add(ctDto2);
        listCtDto.add(ctDto3);

        return listCtDto;
    }

    public static List<RefCommunicationType> mockRefCommunicationTypeList(){

        RefCommunicationType ct1 = mockRefCommunicationType();
        RefCommunicationType ct2 = mockRefCommunicationType();
        ct2.setDescription("Mobil");
        ct2.setType("Mobil");
        RefCommunicationType ct3 = mockRefCommunicationType();
        ct3.setDescription("E-Mail");
        ct3.setType("E-Mail");
        ct3.setTypeEmail(true);

        List<RefCommunicationType> listCt = new ArrayList<>();
        listCt.add(ct1);
        listCt.add(ct2);
        listCt.add(ct3);

        return listCt;
    }

    public static TblInternalPerson mockInternalPerson() {
        TblContact c = new TblContact();
        c.setId( 10L );
        c.setContactType(Constants.CONTACT_TYPE_INTERNAL_PERSON);
        c.setUuid(UUID.randomUUID());
        TblInternalPerson i = new TblInternalPerson();
        i.setId( 12L );
        i.setContact(c);
        i.setFirstName("Wolfi");
        i.setLastName("Weinbrenner");
        i.setTitle("Freiherr");
        i.setDepartment("Forschung");
        i.setUidIdent("111-777");
        i.setUserRef("WWEINB");
        i.setRefPersonType(mockRefPersonType());
        i.setSalutation(mockRefSalutation());
        c.setNote("Teilzeit");
        return i;
    }

    public static InternalPersonDto mockInternalPersonDto() {
        InternalPersonDto ipd = new InternalPersonDto();
        ipd.setContactUuid(UUID.randomUUID());
        ipd.setFirstName("Hella");
        ipd.setLastName("Wahnsinn");
        ipd.setContactType(Constants.CONTACT_TYPE_INTERNAL_PERSON);
        ipd.setTitle("Mrs.");
        ipd.setDepartment("Beschwerdemanagement");
        ipd.setUid("222-888");
        ipd.setUserRef("HWAHNS");
        ipd.setPersonTypeUuid(UUID.randomUUID());
        ipd.setSalutationUuid(UUID.randomUUID());
        ipd.setContactNote("Vorsicht");
        return ipd;
    }

    public static Page<InternalPersonDto> mockInternalPersonDtoPage(){

        InternalPersonDto ip1 = mockInternalPersonDto();

        InternalPersonDto ip2 = new InternalPersonDto();
        ip2.setContactUuid(UUID.randomUUID());
        ip2.setFirstName("Fritz");
        ip2.setLastName("Alter");
        ip2.setContactType(Constants.CONTACT_TYPE_INTERNAL_PERSON);
        ip2.setTitle("Dr.");
        ip2.setDepartment("Geschäftsführung");
        ip2.setUid("333-999");
        ip2.setUserRef("FALTER");
        ip2.setPersonTypeUuid(UUID.randomUUID());
        ip2.setSalutationUuid(UUID.randomUUID());
        ip2.setContactNote("Gründer");

        List<InternalPersonDto> list = Arrays.asList(ip1, ip2);
        return new PageImpl<>(list, Pageable.unpaged(), list.size());
    }

    public static Page<TblInternalPerson> mockTblInternalPersonPage(){

        TblInternalPerson ip1 = mockInternalPerson();

        TblInternalPerson ip2 = new TblInternalPerson();
        ip2.setContact(new TblContact());
        ip2.getContact().setUuid(UUID.randomUUID());
        ip2.setFirstName("Fritz");
        ip2.setLastName("Alter");
        ip2.setTitle("Dr.");
        ip2.setDepartment("Geschäftsführung");
        ip2.setUidIdent("333-999");
        ip2.setUserRef("FALTER");
        ip2.getContact().setNote("Gründer");

        List<TblInternalPerson> list = Arrays.asList(ip1, ip2);
        return new PageImpl<>(list, Pageable.unpaged(), list.size());
    }

    public static TblCompany mockCompany() {
        TblContact c = new TblContact();
        c.setId( 10L );
        c.setContactType(Constants.CONTACT_TYPE_COMPANY);
        c.setUuid(UUID.randomUUID());
        TblCompany tblCompany = new TblCompany();
        tblCompany.setId( 12L );
        tblCompany.setContact(c);
        tblCompany.setCompanyName("Kuemmelbrot");
        tblCompany.setCompanyType("GmbH");
        c.setNote("insolvent");
        return tblCompany;
    }

    public static CompanyDto mockCompanyDto() {
        CompanyDto tblCompany = new CompanyDto();
        tblCompany.setContactUuid(UUID.randomUUID());
        tblCompany.setCompanyName("Kuemmelbrot");
        tblCompany.setCompanyType("GmbH");
        tblCompany.setContactType(Constants.CONTACT_TYPE_COMPANY);

        tblCompany.setContactNote("Vorsicht");
        return tblCompany;
    }

    public static Page<TblCompany> mockCompanyPage(){

        TblCompany com1 = mockCompany();

        TblCompany com2 = mockCompany();
        com2.setCompanyName("Sputnik 2000");
        com2.setCompanyType("AG");

        List<TblCompany> list = Arrays.asList(com1, com2);
        return new PageImpl<>(list, Pageable.unpaged(), list.size());
    }

    public static Page<CompanyDto> mockCompanyDtoPage(){

        CompanyDto com1 = mockCompanyDto();

        CompanyDto com2 = new CompanyDto();
        com2.setContactUuid(UUID.randomUUID());
        com2.setCompanyName("Sputnik 2000");
        com2.setCompanyType("AG");
        com2.setContactType(Constants.CONTACT_TYPE_COMPANY);
        com2.setContactNote("Gründer");

        List<CompanyDto> list = Arrays.asList(com1, com2);
        return new PageImpl<>(list, Pageable.unpaged(), list.size());
    }

    public static TblContactPerson mockTblContactPerson() {
        TblContactPerson cp = new TblContactPerson();
        cp.setCompany(mockCompany());
        cp.setContact(mockTblContact());
        cp.setFirstName("Prober");
        cp.setLastName("Cottwick");
        cp.setRefPersonType(mockRefPersonType());
        cp.setSalutation(mockRefSalutation());
        cp.setContact(mockTblContact());
        return cp;
    }

    public static List<TblContactPerson> mockTblContactPersons() {
        return Arrays.asList(mockTblContactPerson(), mockTblContactPerson());
    }

    public static ContactPersonDto mockContactPersonDto() {
        ContactPersonDto contactPersonDto = new ContactPersonDto();
        contactPersonDto.setCompanyContactUuid(UUID.randomUUID());
        contactPersonDto.setCompanyName("Filligri");
        contactPersonDto.setCompanyType("GmbH");
        contactPersonDto.setCompanyHrNumber("12345");
        contactPersonDto.setFirstName("Prober");
        contactPersonDto.setLastName("Cottwick");
        contactPersonDto.setCompanyType(Constants.CONTACT_TYPE_CONTACT_PERSON);
        contactPersonDto.setTitle("Prof. Dr.");
        contactPersonDto.setContactUuid(UUID.randomUUID());
        contactPersonDto.setContactType("1CP");
        contactPersonDto.setContactNote("eine Notiz");
        contactPersonDto.setSalutationUuid(UUID.randomUUID());
        contactPersonDto.setPersonTypeUuid(UUID.randomUUID());
        return contactPersonDto;
    }

    public static List<ContactPersonDto> mockContactPersonDtos(){

        ContactPersonDto  cp1 = mockContactPersonDto();

        ContactPersonDto cp2 = new ContactPersonDto();
        cp2.setContactUuid(UUID.randomUUID());
        cp2.setFirstName("Pruner");
        cp2.setLastName("Goldwick");
        cp2.setContactType(Constants.CONTACT_TYPE_CONTACT_PERSON);
        cp2.setTitle("Dr.");
        cp2.setContactNote("Gründer");

        return Arrays.asList(cp1, cp2);
    }

    public static TblContact mockTblContact(){
        TblContact tblContact = new TblContact();
        tblContact.setId(5L);
        tblContact.setUuid(UUID.randomUUID());
        tblContact.setNote("Notiz");
        tblContact.setContactType("2EP");

        return tblContact;
    }

    public static ContactDto mockContactDto(){
        ContactDto contactDto = new ContactDto();
        contactDto.setUuid(UUID.randomUUID());
        contactDto.setNote("Notiz");
        contactDto.setContactType("2EP");

        return contactDto;
    }

    public static CommunicationDto mockCommunicationDto(){
        CommunicationDto dto = new CommunicationDto();
        dto.setUuid(UUID.randomUUID());
        dto.setContactUuid(UUID.randomUUID());
        dto.setCommunicationData("030-12345678");
        dto.setCommunicationTypeDescription("Faxgerät");
        dto.setCommunicationTypeType("FAX");
        dto.setCommunicationTypeUuid(UUID.randomUUID());

        return dto;
    }


    public static List<CommunicationDto> mockCommunicationDtoList(){

        List<CommunicationDto> list = new ArrayList<>();

        CommunicationDto communicationDto1 = mockCommunicationDto();

        CommunicationDto communicationDto2 = new CommunicationDto();
        communicationDto2.setUuid(UUID.randomUUID());
        communicationDto2.setContactUuid(UUID.randomUUID());
        communicationDto2.setCommunicationData("030-456789012");
        communicationDto2.setCommunicationTypeDescription("Telefon");
        communicationDto2.setCommunicationTypeType("TEL");
        communicationDto2.setCommunicationTypeUuid(UUID.randomUUID());

        CommunicationDto communicationDto3 = new CommunicationDto();
        communicationDto3.setUuid(UUID.randomUUID());
        communicationDto3.setContactUuid(UUID.randomUUID());
        communicationDto3.setCommunicationData("030-456789012");
        communicationDto3.setCommunicationTypeDescription("Telefon");
        communicationDto3.setCommunicationTypeType("TEL");
        communicationDto3.setCommunicationTypeUuid(UUID.randomUUID());

        list.add(communicationDto1);
        list.add(communicationDto2);
        list.add(communicationDto3);

        return list;
    }

    public static TblCommunication mockTblCommunication(){
        TblCommunication tblCommunication = new TblCommunication();

        tblCommunication.setUuid(UUID.randomUUID());
        tblCommunication.setTblContact(mockTblContact());
        tblCommunication.setCommunicationData("030-55555555");
        tblCommunication.setRefCommunicationType(mockRefCommunicationType());

        return tblCommunication;
    }

    public static List<TblCommunication> mockTblCommunicationsList(){

        List<TblCommunication> list = new ArrayList<>();

        TblCommunication tblCommunicationDto1 = mockTblCommunication();

        TblCommunication tblCommunicationDto2 = new TblCommunication();
        tblCommunicationDto2.setCommunicationData("030-55555555");
        tblCommunicationDto2.setRefCommunicationType(mockRefCommunicationType());
        tblCommunicationDto2.setTblContact(mockTblContact());
        tblCommunicationDto2.setUuid(UUID.randomUUID());

        list.add(tblCommunicationDto1);
        list.add(tblCommunicationDto2);

        return list;
    }

    public static AssignmentModulContactDto mockAssignmentModulContactDto(){

        AssignmentModulContactDto assignmentDto = new AssignmentModulContactDto();

        assignmentDto.setUuid(UUID.randomUUID());
        assignmentDto.setContactUuid(UUID.randomUUID());
        assignmentDto.setAssignmentDate(Date.valueOf("2022-12-24"));
        assignmentDto.setAssignmentNote("nur für Tests");
        assignmentDto.setDeletionLockUntil(Date.valueOf("2022-12-24"));
        assignmentDto.setExpiringDate(Date.valueOf("2022-12-24"));
        assignmentDto.setModulName("Geplante Netzmassnahme");

        return assignmentDto;
    }


    public static List<AssignmentModulContactDto> mockAssignmentModulContactDtoList(){

        List<AssignmentModulContactDto> list = new ArrayList<>();

        AssignmentModulContactDto assignmentDto1 = mockAssignmentModulContactDto();

        AssignmentModulContactDto assignmentDto2 = new AssignmentModulContactDto();
        assignmentDto2.setUuid(UUID.randomUUID());
        assignmentDto2.setContactUuid(UUID.randomUUID());
        assignmentDto2.setAssignmentDate(Date.valueOf("2022-01-24"));
        assignmentDto2.setAssignmentNote("Testuser");
        assignmentDto2.setDeletionLockUntil(Date.valueOf("2022-01-24"));
        assignmentDto2.setExpiringDate(Date.valueOf("2022-01-24"));
        assignmentDto2.setModulName("Ferienkalender");

        AssignmentModulContactDto assignmentDto3 = new AssignmentModulContactDto();
        assignmentDto3.setUuid(UUID.randomUUID());
        assignmentDto3.setContactUuid(UUID.randomUUID());
        assignmentDto3.setAssignmentDate(Date.valueOf("2022-04-24"));
        assignmentDto3.setAssignmentNote("Testkoch");
        assignmentDto3.setDeletionLockUntil(Date.valueOf("2022-04-24"));
        assignmentDto3.setExpiringDate(Date.valueOf("2022-04-24"));
        assignmentDto3.setModulName("Kochdienste");

        list.add(assignmentDto1);
        list.add(assignmentDto2);
        list.add(assignmentDto3);

        return list;
    }

    public static TblAssignmentModulContact mockTblAssignmentModulContact(){

        TblAssignmentModulContact tblAssignment = new TblAssignmentModulContact();

        tblAssignment.setUuid(UUID.randomUUID());
        tblAssignment.setTblContact(mockTblContact());
        tblAssignment.setAssignmentDate(Date.valueOf("2022-12-01"));
        tblAssignment.setAssignmentNote("nur für Tests");
        tblAssignment.setDeletionLockUntil(Date.valueOf("2023-12-01"));
        tblAssignment.setExpiringDate(Date.valueOf("2024-12-01"));
        tblAssignment.setModulName("Reparaturdienste");

        return tblAssignment;
    }

    public static List<TblAssignmentModulContact> mockTblAssignmentsList(){
        List<TblAssignmentModulContact> list = new ArrayList<>();

        TblAssignmentModulContact tblAssignment  = mockTblAssignmentModulContact();

        TblAssignmentModulContact tblAssignment2 = new TblAssignmentModulContact();
        tblAssignment2.setUuid(UUID.randomUUID());
        tblAssignment2.setTblContact(mockTblContact());
        tblAssignment2.setAssignmentDate(Date.valueOf("2020-12-01"));
        tblAssignment2.setAssignmentNote("nur für Tests");
        tblAssignment2.setDeletionLockUntil(Date.valueOf("2025-12-01"));
        tblAssignment2.setExpiringDate(Date.valueOf("2030-12-01"));
        tblAssignment2.setModulName("Störungsstatistik");

        list.add(tblAssignment);
        list.add(tblAssignment2);


        return list;
    }

    public static LdapUser mockLdapUser() {
        LdapUser ldapUser = new LdapUser();
        ldapUser.setUid( UUID.randomUUID().toString() );
        ldapUser.setFirstName("Ludwig");
        ldapUser.setLastName("Lumpensammler");
        ldapUser.setMail("ll@lumpi.de");

        return ldapUser;
    }

    public static KeyCloakUser mockKeyCloakUser() {
        KeyCloakUser keyCloakUser = new KeyCloakUser();
        keyCloakUser.setUsername("ludwigL");
        keyCloakUser.setFirstName("Ludwig");
        keyCloakUser.setLastName("Lumpensammler");
        return keyCloakUser;
    }

    public static List<LdapUser> mockLdapUsers() {
        List<LdapUser> list = new ArrayList<>();
        LdapUser ldapUser2 = new LdapUser();
        ldapUser2.setUid( UUID.randomUUID().toString() );
        ldapUser2.setFirstName("Karl");
        ldapUser2.setLastName("Kleinfink");
        ldapUser2.setTelephoneNumber("99887766");
        list.add( mockLdapUser() );
        list.add( ldapUser2 );
        return list;
    }

    public static List<KeyCloakUser> mockKeycloakUsers() {
        List<KeyCloakUser> list = new ArrayList<>();
        KeyCloakUser keyCloakUser = new KeyCloakUser();
        keyCloakUser.setFirstName("Karl");
        keyCloakUser.setLastName("Kleinfink");
        keyCloakUser.setUsername("karlK");
        list.add( mockKeyCloakUser() );
        list.add( keyCloakUser );
        return list;
    }

    public static Attribute mockLdapAttribute(String value )  {
        Attribute attribute = mock( Attribute.class);
        try {
            when(attribute.get()).thenReturn(value);
        } catch (NamingException e) {
           return null;
        }
        return attribute;
    }
}
