/*
 * 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.plugins.index.reference;

import java.util.Collections;
import java.util.List;

import javax.jcr.PropertyType;

import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.plugins.index.IndexUpdateProvider;
import org.apache.jackrabbit.oak.query.NodeStateNodeTypeInfoProvider;
import org.apache.jackrabbit.oak.query.QueryEngineSettings;
import org.apache.jackrabbit.oak.query.ast.NodeTypeInfo;
import org.apache.jackrabbit.oak.query.ast.NodeTypeInfoProvider;
import org.apache.jackrabbit.oak.query.ast.Operator;
import org.apache.jackrabbit.oak.query.ast.SelectorImpl;
import org.apache.jackrabbit.oak.query.index.FilterImpl;
import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
import org.apache.jackrabbit.oak.spi.commit.EditorHook;
import org.apache.jackrabbit.oak.spi.mount.MountInfoProvider;
import org.apache.jackrabbit.oak.spi.mount.Mounts;
import org.apache.jackrabbit.oak.spi.query.Cursor;
import org.apache.jackrabbit.oak.spi.query.Filter;
import org.apache.jackrabbit.oak.spi.query.QueryIndex;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import static com.google.common.collect.ImmutableList.of;
import static com.google.common.collect.Lists.newArrayList;
import static org.apache.jackrabbit.JcrConstants.JCR_UUID;
import static org.apache.jackrabbit.JcrConstants.NT_BASE;
import static org.apache.jackrabbit.oak.plugins.memory.PropertyStates.createProperty;
import static org.apache.jackrabbit.oak.InitialContentHelper.INITIAL_CONTENT;
import static org.apache.jackrabbit.oak.plugins.memory.PropertyValues.newReference;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;

public class ReferenceIndexTest {

    @Rule
    public ExpectedException thrown = ExpectedException.none();

    @Test
    public void basicReferenceHandling() throws Exception{
        NodeState root = INITIAL_CONTENT;

        NodeBuilder builder = root.builder();
        NodeState before = builder.getNodeState();

        builder.child("a").setProperty(createProperty("foo", "u1", Type.REFERENCE));
        builder.child("b").setProperty(createProperty("foo", "u1", Type.REFERENCE));
        builder.child("c").setProperty(createProperty("foo", "u2", Type.WEAKREFERENCE));

        NodeState after = builder.getNodeState();
        EditorHook hook = new EditorHook(
                new IndexUpdateProvider(new ReferenceEditorProvider()));

        NodeState indexed = hook.processCommit(before, after, CommitInfo.EMPTY);
        FilterImpl f = createFilter(indexed, NT_BASE);
        f.restrictProperty("*", Operator.EQUAL, newReference("u1"), PropertyType.REFERENCE);

        assertFilter(f, new ReferenceIndex(), indexed, of("/a", "/b"));

        FilterImpl f2 = createFilter(indexed, NT_BASE);
        f2.restrictProperty("*", Operator.EQUAL, newReference("u2"), PropertyType.WEAKREFERENCE);
        assertFilter(f2, new ReferenceIndex(), indexed, of("/c"));
    }

    @Test
    public void referenceHandlingWithMounts() throws Exception{
        NodeState root = INITIAL_CONTENT;

        NodeBuilder builder = root.builder();
        NodeState before = builder.getNodeState();

        builder.child("a").child("x").setProperty(createProperty("foo", "u1", Type.REFERENCE));
        builder.child("b").setProperty(createProperty("foo", "u1", Type.REFERENCE));
        builder.child("c").setProperty(createProperty("foo", "u1", Type.WEAKREFERENCE));

        builder.child("d").setProperty(createProperty("foo", "u2", Type.WEAKREFERENCE));
        builder.child("a").child("y").setProperty(createProperty("foo", "u1", Type.WEAKREFERENCE));

        NodeState after = builder.getNodeState();

        MountInfoProvider mip = Mounts.newBuilder()
                .mount("foo", "/a")
                .build();

        EditorHook hook = new EditorHook(
                new IndexUpdateProvider(new ReferenceEditorProvider().with(mip)));

        ReferenceIndex referenceIndex = new ReferenceIndex(mip);

        NodeState indexed = hook.processCommit(before, after, CommitInfo.EMPTY);
        FilterImpl f = createFilter(indexed, NT_BASE);
        f.restrictProperty("*", Operator.EQUAL, newReference("u1"), PropertyType.REFERENCE);

        // System.out.println(NodeStateUtils.toString(NodeStateUtils.getNode(indexed, "/oak:index/reference")));
        assertFilter(f, referenceIndex, indexed, of("/a/x", "/b"));

        FilterImpl f2 = createFilter(indexed, NT_BASE);
        f2.restrictProperty("*", Operator.EQUAL, newReference("u1"), PropertyType.WEAKREFERENCE);
        assertFilter(f2, referenceIndex, indexed, of("/c", "/a/y"));
    }

    @Test
    public void removeReferencedNode() throws Exception{
        NodeState root = INITIAL_CONTENT;

        NodeBuilder builder = root.builder();
        NodeState before = builder.getNodeState();

        builder.child("a").setProperty(createProperty(JCR_UUID, "u1", Type.STRING));
        builder.child("b").setProperty(createProperty("foo", "u1", Type.REFERENCE));

        NodeState after = builder.getNodeState();
        EditorHook hook = new EditorHook(
                new IndexUpdateProvider(new ReferenceEditorProvider()));

        NodeState indexed = hook.processCommit(before, after, CommitInfo.EMPTY);

        builder = indexed.builder();
        builder.getChildNode("a").remove();

        thrown.expect(CommitFailedException.class);
        thrown.expectMessage("OakIntegrity0001: Unable to delete referenced node: u1");
        hook.processCommit(indexed, builder.getNodeState(), CommitInfo.EMPTY);
    }

    @Test
    public void removeWeaklyReferencedNode() throws Exception{
        NodeState root = INITIAL_CONTENT;

        NodeBuilder builder = root.builder();
        NodeState before = builder.getNodeState();

        builder.child("a").setProperty(createProperty(JCR_UUID, "u1", Type.STRING));
        builder.child("b").setProperty(createProperty("foo", "u1", Type.WEAKREFERENCE));

        NodeState after = builder.getNodeState();
        EditorHook hook = new EditorHook(
                new IndexUpdateProvider(new ReferenceEditorProvider()));

        NodeState indexed = hook.processCommit(before, after, CommitInfo.EMPTY);

        builder = indexed.builder();
        builder.getChildNode("a").remove();

        hook.processCommit(indexed, builder.getNodeState(), CommitInfo.EMPTY);
    }

    @SuppressWarnings("Duplicates")
    private static FilterImpl createFilter(NodeState root, String nodeTypeName) {
        NodeTypeInfoProvider nodeTypes = new NodeStateNodeTypeInfoProvider(root);
        NodeTypeInfo type = nodeTypes.getNodeTypeInfo(nodeTypeName);
        SelectorImpl selector = new SelectorImpl(type, nodeTypeName);
        return new FilterImpl(selector, "SELECT * FROM [" + nodeTypeName + "]", new QueryEngineSettings());
    }

    private static List<String> assertFilter(Filter filter, QueryIndex queryIndex,
                                             NodeState indexed, List<String> expected) {
        Cursor cursor = queryIndex.query(filter, indexed);
        List<String> paths = newArrayList();
        while (cursor.hasNext()) {
            paths.add(cursor.next().getPath());
        }
        Collections.sort(paths);
        for (String p : expected) {
            assertTrue("Expected path " + p + " not found", paths.contains(p));
        }
        assertEquals("Result set size is different \nExpected: " +
                expected + "\nActual: " + paths, expected.size(), paths.size());
        return paths;
    }

}