/*
 * 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 com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.plugins.index.ContextAwareCallback;
import org.apache.jackrabbit.oak.plugins.index.IndexCommitCallback;
import org.apache.jackrabbit.oak.plugins.index.IndexUpdateCallback;
import org.apache.jackrabbit.oak.plugins.index.IndexingContext;
import org.apache.jackrabbit.oak.plugins.index.lucene.IndexTracker;
import org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexDefinition;
import org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexEditor;
import org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexEditorContext;
import org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexEditorProvider;
import org.apache.jackrabbit.oak.plugins.index.lucene.TestUtil;
import org.apache.jackrabbit.oak.plugins.index.lucene.hybrid.DocumentQueue;
import org.apache.jackrabbit.oak.plugins.index.search.FulltextIndexConstants;
import org.apache.jackrabbit.oak.spi.commit.CommitContext;
import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
import org.apache.jackrabbit.oak.spi.commit.Editor;
import org.apache.jackrabbit.oak.spi.commit.SimpleCommitContext;
import org.apache.jackrabbit.oak.spi.mount.Mounts;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.junit.Test;

import static org.apache.jackrabbit.oak.InitialContentHelper.INITIAL_CONTENT;
import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.TYPE_LUCENE;
import static org.apache.jackrabbit.oak.plugins.index.lucene.util.LuceneIndexHelper.newLucenePropertyIndexDefinition;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class LuceneIndexEditorProviderTest {
    private NodeState root = INITIAL_CONTENT;
    private NodeBuilder builder = root.builder();

    @Test
    public void readOnlyBuilderUsedForSync() throws Exception {
        LuceneIndexEditorProvider editorProvider = new LuceneIndexEditorProvider(null,
                null,
                null,
                null,
                Mounts.defaultMountInfoProvider());
        editorProvider.setIndexingQueue(mock(DocumentQueue.class));

        IndexUpdateCallback callback = new TestCallback("/oak:index/fooIndex", newCommitInfo(), false, false);
        NodeBuilder defnBuilder = createIndexDefinition("fooIndex").builder();
        Editor editor = editorProvider.getIndexEditor(TYPE_LUCENE, defnBuilder, root, callback);
        LuceneIndexEditor luceneEditor = (LuceneIndexEditor) editor;

        NodeBuilder builderFromContext =
                (NodeBuilder) FieldUtils.readField(luceneEditor.getContext(), "definitionBuilder", true);

        try {
            builderFromContext.setProperty("foo", "bar");
            fail("Should have been read only builder");
        } catch (UnsupportedOperationException ignore) {

        }
    }

    @Test
    public void reuseOldIndexDefinition() throws Exception{
        IndexTracker tracker = mock(IndexTracker.class);
        LuceneIndexEditorProvider editorProvider = new LuceneIndexEditorProvider(null,
                tracker,
                null,
                null,
                Mounts.defaultMountInfoProvider());
        editorProvider.setIndexingQueue(mock(DocumentQueue.class));
        //Set up a different IndexDefinition which needs to be returned
        //from tracker with a marker property
        NodeBuilder testBuilder = createIndexDefinition("fooIndex").builder();
        testBuilder.setProperty("foo", "bar");
        LuceneIndexDefinition defn = new LuceneIndexDefinition(root, testBuilder.getNodeState(), "/foo");
        when(tracker.getIndexDefinition("/oak:index/fooIndex")).thenReturn(defn);

        IndexUpdateCallback callback = new TestCallback("/oak:index/fooIndex", newCommitInfo(), false, false);
        NodeBuilder defnBuilder = createIndexDefinition("fooIndex").builder();
        Editor editor = editorProvider.getIndexEditor(TYPE_LUCENE, defnBuilder, root, callback);
        LuceneIndexEditor luceneEditor = (LuceneIndexEditor) editor;
        LuceneIndexEditorContext context = luceneEditor.getContext();

        //Definition should reflect the marker property
        assertEquals("bar", context.getDefinition().getDefinitionNodeState().getString("foo"));
    }

    @Test
    public void editorNullInCaseOfReindex() throws Exception{
        LuceneIndexEditorProvider editorProvider = new LuceneIndexEditorProvider(null,
                null,
                null,
                null,
                Mounts.defaultMountInfoProvider());
        editorProvider.setIndexingQueue(mock(DocumentQueue.class));
        IndexUpdateCallback callback = new TestCallback("/oak:index/fooIndex", newCommitInfo(), true, false);
        NodeBuilder defnBuilder = createIndexDefinition("fooIndex").builder();
        Editor editor = editorProvider.getIndexEditor(TYPE_LUCENE, defnBuilder, root, callback);
        assertNull(editor);
    }

    private NodeState createIndexDefinition(String idxName) {
        NodeBuilder idx = newLucenePropertyIndexDefinition(builder.child("oak:index"),
                idxName, ImmutableSet.of("foo"), "async");
        TestUtil.enableIndexingMode(idx, FulltextIndexConstants.IndexingMode.NRT);
        LuceneIndexEditorContext.configureUniqueId(idx);
        LuceneIndexDefinition.updateDefinition(idx);
        return idx.getNodeState();
    }

    private CommitInfo newCommitInfo() {
        CommitInfo info = new CommitInfo("admin", "s1",
                ImmutableMap.<String, Object>of(CommitContext.NAME, new SimpleCommitContext()));
        return info;
    }

    private static class TestCallback implements IndexUpdateCallback, IndexingContext, ContextAwareCallback {
        private final String indexPath;
        private final CommitInfo commitInfo;
        private final boolean reindexing;
        private final boolean async;

        private TestCallback(String indexPath, CommitInfo commitInfo, boolean reindexing, boolean async) {
            this.indexPath = indexPath;
            this.commitInfo = commitInfo;
            this.reindexing = reindexing;
            this.async = async;
        }

        @Override
        public String getIndexPath() {
            return indexPath;
        }

        @Override
        public CommitInfo getCommitInfo() {
            return commitInfo;
        }

        @Override
        public boolean isReindexing() {
            return reindexing;
        }

        @Override
        public boolean isAsync() {
            return async;
        }

        @Override
        public void indexUpdateFailed(Exception e) {

        }

        @Override
        public void indexUpdate() throws CommitFailedException {

        }

        @Override
        public IndexingContext getIndexingContext() {
            return this;
        }

        @Override
        public void registerIndexCommitCallback(IndexCommitCallback callback) {

        }
    }

}