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

import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.api.JackrabbitSession;
import org.apache.jackrabbit.commons.JcrUtils;
import org.apache.jackrabbit.oak.jcr.Jcr;
import org.apache.jackrabbit.oak.plugins.index.search.FulltextIndexConstants;
import org.apache.jackrabbit.oak.plugins.index.search.IndexFormatVersion;
import org.apache.jackrabbit.oak.spi.commit.Observer;
import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;

import javax.jcr.Node;
import javax.jcr.Repository;
import javax.jcr.SimpleCredentials;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import javax.jcr.query.RowIterator;
import java.util.Set;

import static com.google.common.collect.Sets.newHashSet;
import static org.apache.jackrabbit.JcrConstants.NT_BASE;
import static org.apache.jackrabbit.JcrConstants.NT_UNSTRUCTURED;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NODE_TYPE;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_PROPERTY_NAME;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_PROPERTY_NAME;
import static org.apache.jackrabbit.oak.plugins.index.search.FulltextIndexConstants.EVALUATE_PATH_RESTRICTION;
import static org.apache.jackrabbit.oak.plugins.index.search.FulltextIndexConstants.INDEX_RULES;
import static org.apache.jackrabbit.oak.plugins.index.search.FulltextIndexConstants.PROPDEF_PROP_NODE_NAME;
import static org.apache.jackrabbit.oak.plugins.index.search.FulltextIndexConstants.PROP_USE_IN_SUGGEST;
import static org.apache.jackrabbit.oak.plugins.index.lucene.TestUtil.shutdown;
import static org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants.NT_OAK_UNSTRUCTURED;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public class LuceneIndexDescendantSuggestionTest {
    private Repository repository = null;
    private JackrabbitSession session = null;
    private Node root = null;

    @Before
    public void before() throws Exception {
        LuceneIndexProvider provider = new LuceneIndexProvider();

        Jcr jcr = new Jcr()
            .with(((QueryIndexProvider) provider))
            .with((Observer) provider)
            .with(new LuceneIndexEditorProvider());

        repository = jcr.createRepository();
        session = (JackrabbitSession) repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
        root = session.getRootNode();

        createContent();
        session.save();
    }

    @After
    public void after() {
        session.logout();
        shutdown(repository);
    }

    private void createContent() throws Exception {
        /*
        Make content with following structure:
        * sugg-idx is a simple index to suggest node names on type "oak:Unstructured"
        * test[1-6] nodes would be "oak:Unstructured".
        * all other nodes, unless required are "nt:unstructured"
        * Index on one sub-tree is on nt:base so that we can do sub-tree suggestion test with unambiguous indices
        */

        //  /oak:index/sugg-idx, /test1
        createSuggestIndex(root, "sugg-idx", NT_OAK_UNSTRUCTURED, PROPDEF_PROP_NODE_NAME);
        root.addNode("test1", NT_OAK_UNSTRUCTURED);

        /*
            /content1
                /tree1
                    /test2
                /tree2
                    /test3
         */
        Node content1 = root.addNode("content1", NT_UNSTRUCTURED);
        Node tree1 = content1.addNode("tree1", NT_UNSTRUCTURED);
        tree1.addNode("test2", NT_OAK_UNSTRUCTURED);
        Node tree2 = content1.addNode("tree2", NT_UNSTRUCTURED);
        tree2.addNode("test3", NT_OAK_UNSTRUCTURED);

        //  /content2/oak:index/sugg-idx, /content2/test4
        Node content2 = root.addNode("content2", NT_UNSTRUCTURED);
        createSuggestIndex(content2, "sugg-idx", NT_OAK_UNSTRUCTURED, PROPDEF_PROP_NODE_NAME);
        content2.addNode("test4", NT_OAK_UNSTRUCTURED);

        //  /content3/oak:index/sugg-idx, /content3/test5, /content3/sC/test6
        Node content3 = root.addNode("content3", NT_UNSTRUCTURED);
        createSuggestIndex(content3, "sugg-idx", NT_BASE, PROPDEF_PROP_NODE_NAME);
        content3.addNode("test5", NT_OAK_UNSTRUCTURED);
        Node subChild = content3.addNode("sC", NT_UNSTRUCTURED);
        subChild.addNode("test6", NT_OAK_UNSTRUCTURED);
    }

    private void createSuggestIndex(Node rootNode, String name, String indexedNodeType, String indexedPropertyName)
        throws Exception {
        Node def = JcrUtils.getOrAddNode(rootNode, INDEX_DEFINITIONS_NAME)
            .addNode(name, INDEX_DEFINITIONS_NODE_TYPE);
        def.setProperty(TYPE_PROPERTY_NAME, LuceneIndexConstants.TYPE_LUCENE);
        def.setProperty(REINDEX_PROPERTY_NAME, true);
        def.setProperty("name", name);
        def.setProperty(FulltextIndexConstants.COMPAT_MODE, IndexFormatVersion.V2.getVersion());
        def.setProperty(EVALUATE_PATH_RESTRICTION, true);

        Node propertyIdxDef = def.addNode(INDEX_RULES, JcrConstants.NT_UNSTRUCTURED)
            .addNode(indexedNodeType, JcrConstants.NT_UNSTRUCTURED)
            .addNode(FulltextIndexConstants.PROP_NODE, JcrConstants.NT_UNSTRUCTURED)
            .addNode("indexedProperty", JcrConstants.NT_UNSTRUCTURED);
        propertyIdxDef.setProperty("analyzed", true);
        propertyIdxDef.setProperty(PROP_USE_IN_SUGGEST, true);
        propertyIdxDef.setProperty("name", indexedPropertyName);
    }

    private String createSuggestQuery(String nodeTypeName, String suggestFor, String rootPath) {
        return "SELECT [rep:suggest()] as suggestion, [jcr:score] as score  FROM [" + nodeTypeName + "]" +
            " WHERE suggest('" + suggestFor + "')" +
            (rootPath==null?"":" AND ISDESCENDANTNODE([" + rootPath + "])");

    }

    private Set<String> getSuggestions(String query) throws Exception {
        QueryManager queryManager = session.getWorkspace().getQueryManager();
        QueryResult result = queryManager.createQuery(query, Query.JCR_SQL2).execute();
        RowIterator rows = result.getRows();

        Set<String> suggestions = newHashSet();
        while (rows.hasNext()) {
            suggestions.add(rows.nextRow().getValue("suggestion").getString());
        }

        return suggestions;
    }

    private void validateSuggestions(String query, Set<String> expected) throws Exception {
        Set<String> suggestions = getSuggestions(query);
        assertEquals("Incorrect suggestions", expected, suggestions);
    }

    //Don't break suggestions :)
    @Test
    public void noDescendantSuggestsAll() throws Exception {
        validateSuggestions(
            createSuggestQuery(NT_OAK_UNSTRUCTURED, "te", null),
            newHashSet("test1", "test2", "test3", "test4", "test5", "test6"));
    }

    //OAK-3994
    @Test
    public void rootIndexWithDescendantConstraint() throws Exception {
        validateSuggestions(
            createSuggestQuery(NT_OAK_UNSTRUCTURED, "te", "/content1"),
            newHashSet("test2", "test3"));
    }

    //OAK-3994
    @Test
    public void descendantSuggestionRequirePathRestrictionIndex() throws Exception {
        Node rootIndexDef = root.getNode("oak:index/sugg-idx");
        rootIndexDef.getProperty(EVALUATE_PATH_RESTRICTION).remove();
        rootIndexDef.setProperty(REINDEX_PROPERTY_NAME, true);
        session.save();

        //Without path restriction indexing, descendant clause shouldn't be respected
        validateSuggestions(
            createSuggestQuery(NT_OAK_UNSTRUCTURED, "te", "/content1"),
            newHashSet("test1", "test2", "test3", "test4", "test5", "test6"));
    }

    @Ignore("OAK-3992")
    @Test
    public void ambiguousSubtreeIndexWithDescendantConstraint() throws Exception {
        String query = createSuggestQuery(NT_OAK_UNSTRUCTURED, "te", "/content2");
        String explainQuery = "EXPLAIN " + createSuggestQuery(NT_OAK_UNSTRUCTURED, "te", "/content2");

        QueryManager queryManager = session.getWorkspace().getQueryManager();
        QueryResult result = queryManager.createQuery(explainQuery, Query.JCR_SQL2).execute();
        RowIterator rows = result.getRows();

        String explanation = rows.nextRow().toString();
        assertTrue("Subtree index should get picked", explanation.contains("lucene:sugg-idx(/content2/oak:index/sugg-idx)"));

        validateSuggestions(query, newHashSet("test4"));
    }

    //OAK-3994
    @Test
    public void unambiguousSubtreeIndexWithDescendantConstraint() throws Exception {
        validateSuggestions(
            createSuggestQuery(NT_BASE, "te", "/content3"),
            newHashSet("test5", "test6"));
    }

    //OAK-3994
    @Test
    public void unambiguousSubtreeIndexWithSubDescendantConstraint() throws Exception {
        validateSuggestions(
            createSuggestQuery(NT_BASE, "te", "/content3/sC"),
            newHashSet("test6"));
    }

    @Ignore("OAK-3993")
    @Test
    public void unionOnTwoDescendants() throws Exception {
        validateSuggestions(
            createSuggestQuery(NT_OAK_UNSTRUCTURED, "te", "/content1") +
                " UNION " +
                createSuggestQuery(NT_BASE, "te", "/content3"),
            newHashSet("test2", "test3", "test5"));
    }
}
