/*
 * 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.util.Set;
import javax.jcr.security.AccessControlManager;
import javax.jcr.security.AccessControlPolicy;

import com.google.common.collect.ImmutableSet;
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.plugins.tree.RootProvider;
import org.apache.jackrabbit.oak.plugins.tree.TreeUtil;
import org.apache.jackrabbit.oak.spi.security.authorization.cug.CugPolicy;
import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.apache.jackrabbit.oak.commons.PathUtils.ROOT_PATH;

public class NestedCugHookTest extends AbstractCugTest {

    protected static void assertNestedCugs(@NotNull Root root, @NotNull RootProvider rootProvider,
            @NotNull String cugHoldingPath, boolean hasCugPolicy, @NotNull String... expectedNestedPaths) {
        Root immutableRoot = rootProvider.createReadOnlyRoot(root);

        Tree tree = immutableRoot.getTree(cugHoldingPath);
        if (hasCugPolicy) {
            assertFalse(tree.hasProperty(HIDDEN_NESTED_CUGS));
            tree = tree.getChild(REP_CUG_POLICY);
        }

        assertTrue(tree.exists());

        if (tree.isRoot()) {
            if (expectedNestedPaths.length == 0) {
                assertFalse(tree.hasProperty(HIDDEN_TOP_CUG_CNT));
            } else {
                assertTrue(tree.hasProperty(HIDDEN_TOP_CUG_CNT));
                assertEquals(Long.valueOf(expectedNestedPaths.length), tree.getProperty(HIDDEN_TOP_CUG_CNT).getValue(Type.LONG));
            }
        } else {
            assertFalse(tree.hasProperty(HIDDEN_TOP_CUG_CNT));
        }

        if (expectedNestedPaths.length == 0) {
            assertFalse(tree.hasProperty(HIDDEN_NESTED_CUGS));
        } else {
            assertTrue(tree.hasProperty(HIDDEN_NESTED_CUGS));

            PropertyState nestedCugs = tree.getProperty(HIDDEN_NESTED_CUGS);
            assertNotNull(nestedCugs);

            Set<String> nestedPaths = ImmutableSet.copyOf(nestedCugs.getValue(Type.PATHS));
            assertEquals(ImmutableSet.copyOf(expectedNestedPaths), nestedPaths);
        }
    }

    protected boolean removeCug(@NotNull String path, boolean doCommit) throws Exception {
        AccessControlManager acMgr = getAccessControlManager(root);
        for (AccessControlPolicy policy : acMgr.getPolicies(path)) {
            if (policy instanceof CugPolicy) {
                acMgr.removePolicy(path, policy);
                if (doCommit) {
                    root.commit();
                }
                return true;
            }
        }
        return false;
    }

    @Test
    public void testToString() {
        assertEquals("NestedCugHook", new NestedCugHook().toString());
    }

    @Test
    public void testAddCug() throws Exception {
        createCug("/content", getTestGroupPrincipal());
        root.commit();

        assertNestedCugs(root, getRootProvider(), "/", false, "/content");
        assertNestedCugs(root, getRootProvider(), "/content", true);
    }

    @Test
    public void testAddNestedCug() throws Exception {
        // create cugs
        // - /content/a     : allow testGroup, deny everyone
        // - /content/aa/bb : allow testGroup, deny everyone
        // - /content/a/b/c : allow everyone,  deny testGroup (isolated)
        // - /content2      : allow everyone,  deny testGroup (isolated)
        setupCugsAndAcls();

        assertNestedCugs(root, getRootProvider(), ROOT_PATH, false, "/content/a", "/content/aa/bb", "/content2");
        assertNestedCugs(root, getRootProvider(), "/content/a", true, "/content/a/b/c");

        // add CUG at /content after having created CUGs in the subtree
        createCug("/content", EveryonePrincipal.getInstance());
        root.commit();
        assertNestedCugs(root, getRootProvider(), ROOT_PATH, false, "/content", "/content2");
        assertNestedCugs(root, getRootProvider(), "/content", true, "/content/a", "/content/aa/bb");
        assertNestedCugs(root, getRootProvider(), "/content/a", true, "/content/a/b/c");
    }

    @Test
    public void testAddNodeWithCug() throws Exception {
        createCug(SUPPORTED_PATH2, EveryonePrincipal.getInstance());

        Tree newTree = TreeUtil.addChild(root.getTree(SUPPORTED_PATH2), "child", NT_OAK_UNSTRUCTURED);
        String path = newTree.getPath();
        createCug(path, getTestGroupPrincipal());
        root.commit();

        assertNestedCugs(root, getRootProvider(), ROOT_PATH, false, SUPPORTED_PATH2);
        assertNestedCugs(root, getRootProvider(), SUPPORTED_PATH2, true, path);
    }

    @Test
    public void testAddNodeWithCugManually() throws Exception {
        createCug(root, SUPPORTED_PATH3, EveryonePrincipal.NAME);

        Tree newTree = TreeUtil.addChild(root.getTree(SUPPORTED_PATH3), "child", NT_OAK_UNSTRUCTURED);
        String path = newTree.getPath();
        createCug(root, path, getTestGroupPrincipal().getName());
        root.commit();

        assertNestedCugs(root, getRootProvider(), ROOT_PATH, false, SUPPORTED_PATH3);
        assertNestedCugs(root, getRootProvider(), SUPPORTED_PATH3, true, path);
    }

    @Test
    public void testAddAtUnsupportedPath() throws Exception {
        String unsupportedPath = UNSUPPORTED_PATH + "/child";

        createCug(root, unsupportedPath, EveryonePrincipal.NAME);
        root.commit();

        assertNestedCugs(root, getRootProvider(), ROOT_PATH, false, unsupportedPath);
    }

    @Test
    public void testAddAtRoot() throws Exception {
        createCug(root, ROOT_PATH, EveryonePrincipal.NAME);
        root.commit();

        assertTrue(root.getTree(ROOT_PATH).hasChild(REP_CUG_POLICY));

        createCug("/content", getTestGroupPrincipal());
        createCug("/content2", EveryonePrincipal.getInstance());
        root.commit();

        assertNestedCugs(root, getRootProvider(), ROOT_PATH, true, "/content", "/content2");
    }

    @Test
    public void testRemoveCug() throws Exception {
        // create cugs at /content
        createCug("/content", getTestGroupPrincipal());
        root.commit();

        // remove CUG at /content
        assertTrue(removeCug("/content", true));
        assertNestedCugs(root, getRootProvider(), ROOT_PATH, false);
    }

    @Test
    public void testRemoveNestedCug() throws Exception {
        // create cugs
        // - /content/a     : allow testGroup, deny everyone
        // - /content/aa/bb : allow testGroup, deny everyone
        // - /content/a/b/c : allow everyone,  deny testGroup (isolated)
        // - /content2      : allow everyone,  deny testGroup (isolated)
        setupCugsAndAcls();

        // remove CUG at /content/a/b/c
        assertTrue(removeCug("/content/a/b/c", true));

        assertNestedCugs(root, getRootProvider(), ROOT_PATH, false, "/content/a", "/content/aa/bb", "/content2");
        assertNestedCugs(root, getRootProvider(), "/content/a", true);
    }

    @Test
    public void testRemoveIntermediateCug() throws Exception {
        // create cugs
        // - /content/a     : allow testGroup, deny everyone
        // - /content/aa/bb : allow testGroup, deny everyone
        // - /content/a/b/c : allow everyone,  deny testGroup (isolated)
        // - /content2      : allow everyone,  deny testGroup (isolated)
        setupCugsAndAcls();

        // remove CUG at /content/a
        assertTrue(removeCug("/content/a", true));

        assertNestedCugs(root, getRootProvider(), ROOT_PATH, false, "/content/aa/bb", "/content2", "/content/a/b/c");
        assertFalse(root.getTree("/content/a").hasChild(REP_CUG_POLICY));
    }

    @Test
    public void testRemoveMultipleCug() throws Exception {
        // create cugs
        // - /content/a     : allow testGroup, deny everyone
        // - /content/aa/bb : allow testGroup, deny everyone
        // - /content/a/b/c : allow everyone,  deny testGroup (isolated)
        // - /content2      : allow everyone,  deny testGroup (isolated)
        setupCugsAndAcls();

        assertTrue(removeCug("/content/a", false));
        assertTrue(removeCug("/content/aa/bb", false));
        root.commit();

        assertNestedCugs(root, getRootProvider(), ROOT_PATH, false, "/content2", "/content/a/b/c");
    }

    @Test
    public void testRemoveMultipleCug2() throws Exception {
        // create cugs
        // - /content/a     : allow testGroup, deny everyone
        // - /content/aa/bb : allow testGroup, deny everyone
        // - /content/a/b/c : allow everyone,  deny testGroup (isolated)
        // - /content2      : allow everyone,  deny testGroup (isolated)
        setupCugsAndAcls();

        assertTrue(removeCug("/content/a", false));
        assertTrue(removeCug("/content/a/b/c", false));
        root.commit();

        assertNestedCugs(root, getRootProvider(), ROOT_PATH, false, "/content/aa/bb", "/content2");
    }

    @Test
    public void testRemoveContentNode() throws Exception {
        // create cugs
        // - /content/a     : allow testGroup, deny everyone
        // - /content/aa/bb : allow testGroup, deny everyone
        // - /content/a/b/c : allow everyone,  deny testGroup (isolated)
        // - /content2      : allow everyone,  deny testGroup (isolated)
        setupCugsAndAcls();

        root.getTree("/content").remove();
        root.commit();

        assertNestedCugs(root, getRootProvider(), ROOT_PATH, false, "/content2");
    }

    @Test
    public void testRemoveContentANode() throws Exception {
        // create cugs
        // - /content/a     : allow testGroup, deny everyone
        // - /content/aa/bb : allow testGroup, deny everyone
        // - /content/a/b/c : allow everyone,  deny testGroup (isolated)
        // - /content2      : allow everyone,  deny testGroup (isolated)
        setupCugsAndAcls();

        root.getTree("/content/a").remove();
        root.commit();

        assertNestedCugs(root, getRootProvider(), ROOT_PATH, false, "/content2", "/content/aa/bb");
    }

    @Test
    public void testRemoveRootCug() throws Exception {
        // add cug at /
        createCug(root, ROOT_PATH, EveryonePrincipal.NAME);
        createCug("/content", getTestGroupPrincipal());
        createCug("/content2", EveryonePrincipal.getInstance());
        root.commit();

        assertTrue(root.getTree(PathUtils.concat(ROOT_PATH, REP_CUG_POLICY)).remove());
        root.commit();

        assertNestedCugs(root, getRootProvider(), ROOT_PATH, false, "/content", "/content2");

        assertTrue(removeCug("/content", true));
        assertNestedCugs(root, getRootProvider(), ROOT_PATH, false, "/content2");

        assertTrue(removeCug("/content2", true));
        assertNestedCugs(root, getRootProvider(), ROOT_PATH, false);
    }

    @Test
    public void testRemoveAndReadd() throws Exception {
        createCug(root, SUPPORTED_PATH3, EveryonePrincipal.NAME);

        Tree newTree = TreeUtil.addChild(root.getTree(SUPPORTED_PATH3), "child", NT_OAK_UNSTRUCTURED);
        String path = newTree.getPath();
        createCug(path, getTestGroupPrincipal());
        root.commit();

        assertNestedCugs(root, getRootProvider(), ROOT_PATH, false, SUPPORTED_PATH3);
        assertNestedCugs(root, getRootProvider(), SUPPORTED_PATH3, true, path);

        removeCug(path, false);
        createCug(path, EveryonePrincipal.getInstance());
        root.commit();

        assertNestedCugs(root, getRootProvider(), SUPPORTED_PATH3, true, path);
    }

    @Test
    public void testMoveToUnsupportedPath() throws Exception {
        createCug(root, SUPPORTED_PATH3, EveryonePrincipal.NAME);

        Tree newTree = TreeUtil.addChild(root.getTree(SUPPORTED_PATH3), "child", NT_OAK_UNSTRUCTURED);
        String path = newTree.getPath();
        createCug(path, getTestGroupPrincipal());
        root.commit();

        String destPath = PathUtils.concat(UNSUPPORTED_PATH, "moved");
        root.move(path, destPath);
        root.commit();

        assertNestedCugs(root, getRootProvider(), SUPPORTED_PATH3, true);
        assertNestedCugs(root, getRootProvider(), ROOT_PATH, false, SUPPORTED_PATH3, destPath);
    }

    @Test
    public void testMoveToSupportedPath() throws Exception {
        createCug(root, SUPPORTED_PATH3, EveryonePrincipal.NAME);

        Tree newTree = TreeUtil.addChild(root.getTree(SUPPORTED_PATH3), "child", NT_OAK_UNSTRUCTURED);
        String path = newTree.getPath();
        createCug(path, getTestGroupPrincipal());
        root.commit();

        String destPath = PathUtils.concat(SUPPORTED_PATH, "moved");
        root.move(path, destPath);
        root.commit();

        assertNestedCugs(root, getRootProvider(), SUPPORTED_PATH3, true);
        assertNestedCugs(root, getRootProvider(), ROOT_PATH, false, SUPPORTED_PATH3, destPath);
    }

    @Test
    public void testMoveToNested() throws Exception {
        createCug(root, SUPPORTED_PATH2, EveryonePrincipal.NAME);
        createCug(root, SUPPORTED_PATH3, EveryonePrincipal.NAME);

        Tree newTree = TreeUtil.addChild(root.getTree(SUPPORTED_PATH3), "child", NT_OAK_UNSTRUCTURED);
        String path = newTree.getPath();
        createCug(path, getTestGroupPrincipal());
        root.commit();

        String destPath = PathUtils.concat(SUPPORTED_PATH2, "moved");
        root.move(path, destPath);
        root.commit();

        assertNestedCugs(root, getRootProvider(), ROOT_PATH, false, SUPPORTED_PATH3, SUPPORTED_PATH2);
        assertNestedCugs(root, getRootProvider(), SUPPORTED_PATH3, true);
        assertNestedCugs(root, getRootProvider(), SUPPORTED_PATH2, true, destPath);
    }
}
