/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.syncope.core.provisioning.java;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.List;
import java.util.Set;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.CipherAlgorithm;
import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
import org.apache.syncope.core.persistence.api.dao.GroupDAO;
import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
import org.apache.syncope.core.persistence.api.dao.RealmDAO;
import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
import org.apache.syncope.core.persistence.api.entity.EntityFactory;
import org.apache.syncope.core.persistence.api.entity.group.Group;
import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
import org.apache.syncope.core.persistence.api.entity.resource.Provision;
import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount;
import org.apache.syncope.core.persistence.api.entity.user.UDynGroupMembership;
import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
import org.apache.syncope.core.persistence.api.entity.user.User;
import org.apache.syncope.core.provisioning.api.MappingManager;
import org.identityconnectors.common.security.SecurityUtil;
import org.identityconnectors.framework.common.objects.Attribute;
import org.identityconnectors.framework.common.objects.AttributeUtil;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.identityconnectors.framework.common.objects.OperationalAttributes;

@Transactional("Master")
public class DefaultMappingManagerTest extends AbstractTest {

    @Autowired
    private MappingManager mappingManager;

    @Autowired
    private UserDAO userDAO;

    @Autowired
    private ExternalResourceDAO resourceDAO;

    @Autowired
    private RealmDAO realmDAO;

    @Autowired
    private GroupDAO groupDAO;

    @Autowired
    private AnyTypeClassDAO anyTypeClassDAO;

    @Autowired
    private PlainSchemaDAO plainSchemaDAO;

    @Autowired
    private AnyUtilsFactory anyUtilsFactory;

    @Autowired
    private EntityFactory entityFactory;

    @Test
    public void prepareAttrsForUser() {
        User bellini = userDAO.findByUsername("bellini");
        ExternalResource ldap = resourceDAO.find("resource-ldap");
        Provision provision = ldap.getProvision(AnyTypeKind.USER.name()).get();

        assertNotEquals(CipherAlgorithm.AES, bellini.getCipherAlgorithm());

        // 1. with clear-text password
        Pair<String, Set<Attribute>> attrs = mappingManager.prepareAttrsFromAny(
                bellini,
                "Password123",
                true,
                Boolean.TRUE,
                provision);
        assertEquals("bellini", attrs.getLeft());
        assertEquals(
                "uid=bellini,ou=people,o=isp",
                AttributeUtil.getNameFromAttributes(attrs.getRight()).getNameValue());
        assertEquals("Password123", SecurityUtil.decrypt(AttributeUtil.getPasswordValue(attrs.getRight())));

        // 2. with changePwd == false
        attrs = mappingManager.prepareAttrsFromAny(
                bellini,
                "Password123",
                false,
                Boolean.TRUE,
                provision);
        assertNull(AttributeUtil.getPasswordValue(attrs.getRight()));

        // 3. with no clear-text password but random password generation enabled
        ldap.setRandomPwdIfNotProvided(true);
        ldap = resourceDAO.save(ldap);
        entityManager().flush();

        String encPassword = bellini.getPassword();
        attrs = mappingManager.prepareAttrsFromAny(
                bellini,
                null,
                true,
                Boolean.TRUE,
                provision);
        assertNotEquals(encPassword, SecurityUtil.decrypt(AttributeUtil.getPasswordValue(attrs.getRight())));

        // 4. with no clear-text password and random password generation disabled
        ldap.setRandomPwdIfNotProvided(false);
        resourceDAO.save(ldap);
        entityManager().flush();

        attrs = mappingManager.prepareAttrsFromAny(
                bellini,
                null,
                true,
                Boolean.TRUE,
                provision);
        assertNull(AttributeUtil.getPasswordValue(attrs.getRight()));

        // 5. with no clear-text password, random password generation disabled but AES
        bellini.setPassword("newPassword123", CipherAlgorithm.AES);
        userDAO.save(bellini);
        entityManager().flush();

        assertEquals(CipherAlgorithm.AES, bellini.getCipherAlgorithm());

        attrs = mappingManager.prepareAttrsFromAny(
                bellini,
                null,
                true,
                Boolean.TRUE,
                provision);
        assertEquals("newPassword123", SecurityUtil.decrypt(AttributeUtil.getPasswordValue(attrs.getRight())));
    }

    @Test
    public void prepareAttrsForLinkedAccount() {
        User vivaldi = userDAO.findByUsername("vivaldi");
        ExternalResource ldap = resourceDAO.find("resource-ldap");
        Provision provision = ldap.getProvision(AnyTypeKind.USER.name()).get();

        LinkedAccount account = entityFactory.newEntity(LinkedAccount.class);
        account.setConnObjectKeyValue("admin");
        account.setResource(ldap);
        account.setOwner(vivaldi);
        account.setSuspended(Boolean.FALSE);
        account.setPassword("Password321", CipherAlgorithm.AES);
        vivaldi.add(account);

        vivaldi = userDAO.save(vivaldi);
        entityManager().flush();

        // 1. with account password and clear-text default password
        Set<Attribute> attrs = mappingManager.prepareAttrsFromLinkedAccount(
                vivaldi,
                account,
                "Password123",
                true,
                provision);
        assertEquals("admin", AttributeUtil.getStringValue(AttributeUtil.find("cn", attrs)));
        assertEquals("Password321", SecurityUtil.decrypt(AttributeUtil.getPasswordValue(attrs)));
        assertTrue(AttributeUtil.getBooleanValue(AttributeUtil.find(OperationalAttributes.ENABLE_NAME, attrs)));

        // 2. without account password and clear-text default password
        account.setEncodedPassword(null, null);

        attrs = mappingManager.prepareAttrsFromLinkedAccount(
                vivaldi,
                account,
                "Password123",
                true,
                provision);
        assertEquals("Password123", SecurityUtil.decrypt(AttributeUtil.getPasswordValue(attrs)));

        // 3. with changePwd == false
        attrs = mappingManager.prepareAttrsFromLinkedAccount(
                vivaldi,
                account,
                "Password123",
                false,
                provision);
        assertNull(AttributeUtil.getPasswordValue(attrs));

        // 4. without account password, no clear-text password but random password generation enabled
        ldap.setRandomPwdIfNotProvided(true);
        ldap = resourceDAO.save(ldap);
        entityManager().flush();

        String encPassword = vivaldi.getPassword();
        attrs = mappingManager.prepareAttrsFromLinkedAccount(
                vivaldi,
                account,
                null,
                true,
                provision);
        assertNotEquals(encPassword, SecurityUtil.decrypt(AttributeUtil.getPasswordValue(attrs)));

        // 5. without account password, no clear-text password and random password generation disabled
        ldap.setRandomPwdIfNotProvided(false);
        resourceDAO.save(ldap);
        entityManager().flush();

        attrs = mappingManager.prepareAttrsFromLinkedAccount(
                vivaldi,
                account,
                null,
                true,
                provision);
        assertNull(AttributeUtil.getPasswordValue(attrs));
    }

    @Test
    public void issueSYNCOPE1583() {
        // 0. create user matching the condition below
        User user = entityFactory.newEntity(User.class);
        user.setUsername("username");
        user.setRealm(realmDAO.findByFullPath("/even/two"));
        user.add(anyTypeClassDAO.find("other"));

        UPlainAttr cool = entityFactory.newEntity(UPlainAttr.class);
        cool.setOwner(user);
        cool.setSchema(plainSchemaDAO.find("cool"));
        cool.add("true", anyUtilsFactory.getInstance(AnyTypeKind.USER));
        user.add(cool);

        user = userDAO.save(user);
        String newUserKey = user.getKey();
        assertNotNull(newUserKey);

        // 1. update group with dynamic membership
        Group group = groupDAO.findByName("root");
        assertNotNull(group);

        UDynGroupMembership dynMembership = entityFactory.newEntity(UDynGroupMembership.class);
        dynMembership.setFIQLCond("cool==true");
        dynMembership.setGroup(group);
        group.setUDynMembership(dynMembership);

        group = groupDAO.saveAndRefreshDynMemberships(group);
        assertNotNull(group);

        entityManager().flush();

        // 2. verify that dynamic membership is in place
        assertTrue(userDAO.findAllGroupKeys(user).contains(group.getKey()));

        // 3. check propagation attrs
        ExternalResource csv = resourceDAO.find("resource-csv");
        Provision provision = csv.getProvision(AnyTypeKind.USER.name()).get();
        assertNotNull(provision);

        Pair<String, Set<Attribute>> attrs = mappingManager.prepareAttrsFromAny(
                user,
                null,
                false,
                Boolean.TRUE,
                provision);
        assertTrue(attrs.getRight().stream().anyMatch(
                attr -> "theirgroup".equals(attr.getName()) && List.of("sx-dx").equals(attr.getValue())));
    }
}
