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

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

import org.apache.commons.io.FileUtils;
import org.apache.jackrabbit.oak.InitialContent;
import org.apache.jackrabbit.oak.Oak;
import org.apache.jackrabbit.oak.api.ContentRepository;
import org.apache.jackrabbit.oak.plugins.blob.BlobTrackingStore;
import org.apache.jackrabbit.oak.plugins.blob.datastore.BlobIdTracker;
import org.apache.jackrabbit.oak.plugins.blob.datastore.DataStoreBlobStore;
import org.apache.jackrabbit.oak.plugins.blob.datastore.OakFileDataStore;
import org.apache.jackrabbit.oak.plugins.index.AsyncIndexUpdate;
import org.apache.jackrabbit.oak.plugins.index.lucene.IndexCopier;
import org.apache.jackrabbit.oak.plugins.index.lucene.directory.ActiveDeletedBlobCollectorFactory
    .ActiveDeletedBlobCollectorImpl;
import org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexEditorProvider;
import org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexProvider;
import org.apache.jackrabbit.oak.plugins.index.search.ExtractedTextCache;
import org.apache.jackrabbit.oak.segment.SegmentNodeStoreBuilders;
import org.apache.jackrabbit.oak.segment.file.FileStore;
import org.apache.jackrabbit.oak.segment.file.FileStoreBuilder;
import org.apache.jackrabbit.oak.spi.blob.GarbageCollectableBlobStore;
import org.apache.jackrabbit.oak.spi.commit.Observer;
import org.apache.jackrabbit.oak.spi.mount.Mounts;
import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
import org.apache.jackrabbit.oak.spi.security.OpenSecurityProvider;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import static com.google.common.collect.ImmutableSet.of;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Sets.newHashSet;
import static org.apache.jackrabbit.oak.spi.cluster.ClusterRepositoryInfo.getOrCreateId;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public class ActiveDeletedBlobSyncTrackerTest extends AbstractActiveDeletedBlobTest {
    @Rule
    public TemporaryFolder blobTrackerRoot = new TemporaryFolder(new File("target"));

    @Override
    protected ContentRepository createRepository() {
        try {
            File blobCollectorDeleted = new File(blobCollectionRoot.getRoot(), "deleted-blobs");
            blobCollectorDeleted.mkdirs();
            adbc = new ActiveDeletedBlobCollectorImpl(clock, new File(blobCollectionRoot.getRoot(), "deleted-blobs"),
                executorService);

            IndexCopier copier = createIndexCopier();
            editorProvider =
                new LuceneIndexEditorProvider(copier, null, new ExtractedTextCache(10 * FileUtils.ONE_MB,
                    100), null,
                    Mounts.defaultMountInfoProvider(), adbc);
            provider = new LuceneIndexProvider(copier);

            OakFileDataStore ds = new OakFileDataStore();
            ds.setMinRecordLength(10);
            ds.init(fileDataStoreRoot.getRoot().getAbsolutePath());
            DataStoreBlobStore dsbs = new DataStoreBlobStore(ds);
            this.blobStore = new AbstractActiveDeletedBlobTest.CountingBlobStore(dsbs);

            FileStore store = FileStoreBuilder.fileStoreBuilder(temporaryFolder.getRoot()).withMemoryMapping(false)
                .withBlobStore(blobStore).build();
            nodeStore = SegmentNodeStoreBuilders.builder(store).build();
            BlobTrackingStore trackingStore = (BlobTrackingStore) blobStore;
            trackingStore.addTracker(
                new BlobIdTracker(blobTrackerRoot.getRoot().getAbsolutePath(), getOrCreateId(nodeStore), 600,
                    dsbs));
            // set the blob store to skip writing blobs through the node store
            editorProvider.setBlobStore(blobStore);

            asyncIndexUpdate = new AsyncIndexUpdate("async", nodeStore, editorProvider);
            return new Oak(nodeStore).with(new InitialContent()).with(new OpenSecurityProvider())
                .with((QueryIndexProvider) provider).with((Observer) provider).with(editorProvider)
                .createContentRepository();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    // OAK-6504
    @Test
    public void syncActiveDeletionWithBlobTracker() throws Exception {
        createIndex("test1", of("propa"));
        root.getTree("/oak:index/counter").remove();
        root.commit();
        asyncIndexUpdate.run();
        long initialNumChunks = blobStore.numChunks;

        root.getTree("/").addChild("test").setProperty("propa", "foo");
        root.commit();
        asyncIndexUpdate.run();
        long firstCommitNumChunks = blobStore.numChunks;
        adbc.purgeBlobsDeleted(0, blobStore);//hack to purge file
        long time = clock.getTimeIncreasing();
        long hackPurgeNumChunks = blobStore.numChunks;
        assertEquals("Hack purge must not purge any blob (first commit)",
                firstCommitNumChunks, hackPurgeNumChunks);

        root.getTree("/").addChild("test").setProperty("propa", "foo1");
        root.commit();
        asyncIndexUpdate.run();
        long secondCommitNumChunks = blobStore.numChunks;
        adbc.purgeBlobsDeleted(0, blobStore);//hack to purge file
        hackPurgeNumChunks = blobStore.numChunks;
        assertEquals("Hack purge must not purge any blob (second commit)",
            secondCommitNumChunks, hackPurgeNumChunks);

        adbc.purgeBlobsDeleted(time, blobStore);
        adbc.getBlobDeletionCallback();
        long firstGCNumChunks = blobStore.numChunks;

        assertTrue("First commit must create some chunks", firstCommitNumChunks > initialNumChunks);
        assertTrue("First commit must create some chunks", secondCommitNumChunks > firstCommitNumChunks);
        assertTrue("First GC should delete some chunks", firstGCNumChunks < secondCommitNumChunks);

        assertTrackedDeleted(blobStore.getAllChunkIds(-1), blobStore);
    }

    private static void assertTrackedDeleted(Iterator<String> afterDeletions,
        GarbageCollectableBlobStore blobStore) throws IOException {

        List<String> afterDeletionIds = newArrayList(afterDeletions);
        // get the currently tracked ones
        ArrayList<String> trackedIds = newArrayList(((BlobTrackingStore) blobStore).getTracker().get());
        assertEquals("Tracked ids length different from current blob list",
            trackedIds.size(), afterDeletionIds.size());
        assertTrue("Tracked ids different from current blob list",
            newHashSet(trackedIds).equals(newHashSet(afterDeletionIds)));
    }
}
