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

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.apache.jackrabbit.oak.plugins.index.lucene.IndexCopier;
import org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexDefinition;
import org.apache.jackrabbit.oak.plugins.index.lucene.TestUtil;
import org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexEditorContext;
import org.apache.jackrabbit.oak.plugins.index.lucene.reader.LuceneIndexReader;
import org.apache.jackrabbit.oak.plugins.index.lucene.writer.LuceneIndexWriter;
import org.apache.jackrabbit.oak.plugins.index.search.FulltextIndexConstants;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.stats.StatisticsProvider;
import org.apache.lucene.document.Document;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import static com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor;
import static org.apache.jackrabbit.oak.plugins.index.lucene.FieldFactory.newPathField;
import static org.apache.jackrabbit.oak.InitialContentHelper.INITIAL_CONTENT;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

public class NRTIndexTest {
    @Rule
    public TemporaryFolder temporaryFolder = new TemporaryFolder(new File("target"));

    private NodeState root = INITIAL_CONTENT;
    private NodeBuilder builder = root.builder();

    private IndexCopier indexCopier;
    private NRTIndexFactory indexFactory;

    @Before
    public void setUp() throws IOException {
        indexCopier = new IndexCopier(sameThreadExecutor(), temporaryFolder.getRoot());
        indexFactory = new NRTIndexFactory(indexCopier, StatisticsProvider.NOOP);
        indexFactory.setAssertAllResourcesClosed(true);
        LuceneIndexEditorContext.configureUniqueId(builder);
    }

    @After
    public void cleanup() throws IOException {
        indexFactory.close();
        indexCopier.close();
    }

    @Test
    public void getReaderWithoutWriter() throws Exception{
        LuceneIndexDefinition idxDefn = getSyncIndexDefinition("/foo");

        NRTIndex idx1 = indexFactory.createIndex(idxDefn);
        List<LuceneIndexReader> readers = idx1.getReaders();
        assertNotNull(readers);
        assertTrue(readers.isEmpty());

        idx1.close();
        assertTrue(idx1.isClosed());

        //Closing multiple times should not raise exception
        idx1.close();
    }

    @Test
    public void writerCreation() throws Exception{
        LuceneIndexDefinition idxDefn = getSyncIndexDefinition("/foo");
        NRTIndex idx = indexFactory.createIndex(idxDefn);
        LuceneIndexWriter writer = idx.getWriter();

        assertNotNull(writer);
        assertNotNull(idx.getIndexDir());
        List<LuceneIndexReader> readers = idx.getReaders();
        assertEquals(1, readers.size());

        LuceneIndexWriter writer2 = idx.getWriter();
        assertSame(writer, writer2);
    }

    @Test
    public void dirDeletedUponClose() throws Exception{
        LuceneIndexDefinition idxDefn = getSyncIndexDefinition("/foo");
        NRTIndex idx = indexFactory.createIndex(idxDefn);
        LuceneIndexWriter writer = idx.getWriter();
        File indexDir = idx.getIndexDir();

        assertTrue(indexDir.exists());

        idx.close();
        assertFalse(indexDir.exists());

        try{
            idx.getReaders();
            fail();
        } catch (IllegalStateException ignore){

        }

        try{
            idx.getWriter();
            fail();
        } catch (IllegalStateException ignore){

        }
    }

    @Test
    public void multipleUpdateForSamePath() throws Exception{
        LuceneIndexDefinition idxDefn = getSyncIndexDefinition("/foo");
        NRTIndex idx = indexFactory.createIndex(idxDefn);
        LuceneIndexWriter writer = idx.getWriter();

        Document document = new Document();
        document.add(newPathField("/a/b"));

        writer.updateDocument("/a/b", document);
        assertEquals(1, idx.getPrimaryReaderForTest().numDocs());

        writer.updateDocument("/a/b", document);

        //Update for same path should not lead to deletion
        assertEquals(2, idx.getPrimaryReaderForTest().numDocs());
        assertEquals(0, idx.getPrimaryReaderForTest().numDeletedDocs());
    }

    @Test
    public void previousIndexInitialized() throws Exception{
        LuceneIndexDefinition idxDefn = getSyncIndexDefinition("/foo");
        NRTIndex idx1 = indexFactory.createIndex(idxDefn);
        LuceneIndexWriter w1 = idx1.getWriter();

        Document d1 = new Document();
        d1.add(newPathField("/a/b"));
        w1.updateDocument("/a/b", d1);

        NRTIndex idx2 = indexFactory.createIndex(idxDefn);
        assertEquals(1, idx2.getReaders().size());

        LuceneIndexWriter w2 = idx2.getWriter();
        assertEquals(2, idx2.getReaders().size());

        assertNotEquals(idx1.getIndexDir(), idx2.getIndexDir());
    }

    @Test
    public void sameReaderIfNoChange() throws Exception{
        LuceneIndexDefinition idxDefn = getSyncIndexDefinition("/foo");
        NRTIndex idx1 = indexFactory.createIndex(idxDefn);
        LuceneIndexWriter w1 = idx1.getWriter();

        Document d1 = new Document();
        d1.add(newPathField("/a/b"));
        w1.updateDocument("/a/b", d1);

        List<LuceneIndexReader> readers = idx1.getReaders();
        List<LuceneIndexReader> readers2 = idx1.getReaders();

        assertSame(readers, readers2);

        w1.updateDocument("/a/b", d1);
        List<LuceneIndexReader> readers3 = idx1.getReaders();
        assertNotSame(readers2, readers3);
    }

    private LuceneIndexDefinition getSyncIndexDefinition(String indexPath) {
        TestUtil.enableIndexingMode(builder, FulltextIndexConstants.IndexingMode.NRT);

        return new LuceneIndexDefinition(root, builder.getNodeState(), indexPath);
    }



}