/*
 * 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.jackrabbit.oak.spi.security.authorization.cug.impl;

import java.security.Principal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import javax.jcr.RepositoryException;
import javax.jcr.security.AccessControlException;
import javax.jcr.security.AccessControlPolicy;
import javax.jcr.security.AccessControlPolicyIterator;
import javax.jcr.security.Privilege;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlPolicy;
import org.apache.jackrabbit.api.security.principal.PrincipalManager;
import org.apache.jackrabbit.commons.iterator.AccessControlPolicyIteratorAdapter;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Root;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.namepath.NamePathMapper;
import org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants;
import org.apache.jackrabbit.oak.plugins.tree.TreeUtil;
import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.PolicyOwner;
import org.apache.jackrabbit.oak.spi.security.authorization.cug.CugPolicy;
import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
import org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AbstractAccessControlManager;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions;
import org.apache.jackrabbit.oak.spi.security.principal.PrincipalConfiguration;
import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.apache.jackrabbit.oak.api.Type.NAMES;

/**
 * Implementation of the {@link org.apache.jackrabbit.api.security.JackrabbitAccessControlManager}
 * interface that allows to create, modify and remove closed user group policies.
 */
class CugAccessControlManager extends AbstractAccessControlManager implements CugConstants, PolicyOwner {

    private static final Logger log = LoggerFactory.getLogger(CugAccessControlManager.class);

    private final Set<String> supportedPaths;
    private final ConfigurationParameters config;
    private final PrincipalManager principalManager;

    public CugAccessControlManager(@NotNull Root root,
                                   @NotNull NamePathMapper namePathMapper,
                                   @NotNull SecurityProvider securityProvider,
                                   @NotNull Set<String> supportedPaths) {
        super(root, namePathMapper, securityProvider);

        this.supportedPaths = supportedPaths;

        config = securityProvider.getConfiguration(AuthorizationConfiguration.class).getParameters();
        principalManager = securityProvider.getConfiguration(PrincipalConfiguration.class).getPrincipalManager(root, namePathMapper);
    }

    //-----------------------------------------------< AccessControlManager >---

    @NotNull
    @Override
    public Privilege[] getSupportedPrivileges(@Nullable String absPath) throws RepositoryException {
        if (isSupportedPath(getOakPath(absPath))) {
            return new Privilege[] {privilegeFromName(PrivilegeConstants.JCR_READ)};
        } else {
            return new Privilege[0];
        }
    }

    @Override
    public AccessControlPolicy[] getPolicies(String absPath) throws RepositoryException {
        String oakPath = getOakPath(absPath);
        if (oakPath != null && isSupportedPath(oakPath)) {
            CugPolicy cug = getCugPolicy(oakPath);
            if (cug != null) {
                return new AccessControlPolicy[]{cug};
            }
        }
        return new AccessControlPolicy[0];
    }

    @Override
    public AccessControlPolicy[] getEffectivePolicies(String absPath) throws RepositoryException {
        String oakPath = getOakPath(absPath);
        getTree(oakPath, Permissions.READ_ACCESS_CONTROL, true);

        boolean enabled = config.getConfigValue(CugConstants.PARAM_CUG_ENABLED, false);
        if (enabled) {
            Root r = getRoot().getContentSession().getLatestRoot();
            List<AccessControlPolicy> effective = new ArrayList<>();
            while (oakPath != null) {
                if (isSupportedPath(oakPath)) {
                    CugPolicy cug = getCugPolicy(oakPath, r.getTree(oakPath));
                    if (cug != null) {
                        effective.add(cug);
                    }
                }
                oakPath = (PathUtils.denotesRoot(oakPath)) ? null : PathUtils.getAncestorPath(oakPath, 1);
            }
            return effective.toArray(new AccessControlPolicy[effective.size()]);
        } else {
            return new AccessControlPolicy[0];
        }
    }

    @Override
    public AccessControlPolicyIterator getApplicablePolicies(String absPath) throws RepositoryException {
        String oakPath = getOakPath(absPath);
        if (oakPath == null || !isSupportedPath(oakPath)) {
            return AccessControlPolicyIteratorAdapter.EMPTY;
        } else {
            CugPolicy cug = getCugPolicy(oakPath);
            if (cug == null) {
                cug = new CugPolicyImpl(oakPath, getNamePathMapper(), principalManager, CugUtil.getImportBehavior(config));
                return new AccessControlPolicyIteratorAdapter(ImmutableSet.of(cug));
            } else {
                return AccessControlPolicyIteratorAdapter.EMPTY;
            }
        }
    }

    @Override
    public void removePolicy(String absPath, AccessControlPolicy policy) throws RepositoryException {
        String oakPath = getOakPath(absPath);
        if (isSupportedPath(oakPath)) {
            checkValidPolicy(absPath, policy);

            Tree tree = getTree(oakPath, Permissions.MODIFY_ACCESS_CONTROL, true);
            Tree cug = tree.getChild(REP_CUG_POLICY);
            if (!CugUtil.definesCug(cug)) {
                throw new AccessControlException("Unexpected primary type of node rep:cugPolicy.");
            } else {
                // remove the rep:CugMixin if it has been explicitly added upon setPolicy
                Set<String> mixins = Sets.newHashSet(TreeUtil.getNames(tree, NodeTypeConstants.JCR_MIXINTYPES));
                if (mixins.remove(MIX_REP_CUG_MIXIN)) {
                    tree.setProperty(JcrConstants.JCR_MIXINTYPES, mixins, NAMES);
                } else {
                    log.debug("Cannot remove mixin type " + MIX_REP_CUG_MIXIN);
                }
                cug.remove();
            }
        } else {
            throw new AccessControlException("Unsupported path: " + absPath);
        }
    }

    @Override
    public void setPolicy(String absPath, AccessControlPolicy policy) throws RepositoryException {
        String oakPath = getOakPath(absPath);
        if (isSupportedPath(oakPath)) {
            checkValidPolicy(absPath, policy);

            Tree tree = getTree(oakPath, Permissions.MODIFY_ACCESS_CONTROL, true);
            Tree typeRoot = getRoot().getTree(NodeTypeConstants.NODE_TYPES_PATH);
            if (!TreeUtil.isNodeType(tree, MIX_REP_CUG_MIXIN, typeRoot)) {
                TreeUtil.addMixin(tree, MIX_REP_CUG_MIXIN, typeRoot, null);
            }
            Tree cug;
            if (tree.hasChild(REP_CUG_POLICY)) {
                cug = tree.getChild(REP_CUG_POLICY);
                if (!CugUtil.definesCug(cug)) {
                    throw new AccessControlException("Unexpected primary type of node rep:cugPolicy.");
                }
            } else {
                cug = TreeUtil.addChild(tree, REP_CUG_POLICY, NT_REP_CUG_POLICY, typeRoot, null);
            }
            cug.setProperty(REP_PRINCIPAL_NAMES, ((CugPolicyImpl) policy).getPrincipalNames(), Type.STRINGS);
        } else {
            throw new AccessControlException("Unsupported path: " + absPath);
        }
    }

    //-------------------------------------< JackrabbitAccessControlManager >---

    @Override
    public JackrabbitAccessControlPolicy[] getApplicablePolicies(Principal principal) throws RepositoryException {
        // editing by 'principal' is not supported
        return new JackrabbitAccessControlPolicy[0];
    }

    @Override
    public JackrabbitAccessControlPolicy[] getPolicies(Principal principal) throws RepositoryException {
        // editing by 'principal' is not supported
        return new JackrabbitAccessControlPolicy[0];
    }

    @Override
    public AccessControlPolicy[] getEffectivePolicies(Set<Principal> principals) throws RepositoryException {
        // editing by 'principal' is not supported
        return new AccessControlPolicy[0];
    }

    //--------------------------------------------------------< PolicyOwner >---
    @Override
    public boolean defines(@Nullable String absPath, @NotNull AccessControlPolicy accessControlPolicy) {
        return isValidPolicy(absPath, accessControlPolicy);
    }

    //--------------------------------------------------------------------------

    private boolean isSupportedPath(@Nullable String oakPath) throws RepositoryException {
        checkValidPath(oakPath);
        return CugUtil.isSupportedPath(oakPath, supportedPaths);
    }

    private void checkValidPath(@Nullable String oakPath) throws RepositoryException {
        if (oakPath != null) {
            getTree(oakPath, Permissions.NO_PERMISSION, false);
        }
    }

    @Nullable
    private CugPolicy getCugPolicy(@NotNull String oakPath) throws RepositoryException {
        return getCugPolicy(oakPath, getTree(oakPath, Permissions.READ_ACCESS_CONTROL, true));
    }

    @Nullable
    private CugPolicy getCugPolicy(@NotNull String oakPath, @NotNull Tree tree) {
        Tree cug = tree.getChild(REP_CUG_POLICY);
        if (CugUtil.definesCug(cug)) {
            return new CugPolicyImpl(oakPath, getNamePathMapper(), principalManager, CugUtil.getImportBehavior(config), getPrincipals(cug));
        } else {
            return null;
        }
    }

    private Set<Principal> getPrincipals(@NotNull Tree cugTree) {
        PropertyState property = cugTree.getProperty(REP_PRINCIPAL_NAMES);
        if (property == null) {
            return Collections.emptySet();
        } else {
            return ImmutableSet.copyOf(Iterables.transform(property.getValue(Type.STRINGS), principalName -> {
                Principal principal = principalManager.getPrincipal(principalName);
                if (principal == null) {
                    log.debug("Unknown principal " + principalName);
                    principal = new PrincipalImpl(principalName);
                }
                return principal;
            }));
        }
    }

    private static boolean isValidPolicy(@Nullable String absPath, @NotNull AccessControlPolicy policy) {
        return policy instanceof CugPolicyImpl && ((CugPolicyImpl) policy).getPath().equals(absPath);
    }

    private static void checkValidPolicy(@Nullable String absPath, @NotNull AccessControlPolicy policy) throws AccessControlException {
        if (!(policy instanceof CugPolicyImpl)) {
            throw new AccessControlException("Unsupported policy implementation: " + policy);
        }

        CugPolicyImpl cug = (CugPolicyImpl) policy;
        if (!cug.getPath().equals(absPath)) {
            throw new AccessControlException("Path mismatch: Expected " + cug.getPath() + ", Found: " + absPath);
        }
    }
}
