/*
 * 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.cassandra.index.sasi.conf;

import java.io.File;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import org.apache.cassandra.db.marshal.AbstractType;
import org.apache.cassandra.index.sasi.SSTableIndex;
import org.apache.cassandra.index.sasi.conf.view.View;
import org.apache.cassandra.io.sstable.format.SSTableReader;
import org.apache.cassandra.utils.Pair;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** a pared-down version of DataTracker and DT.View. need one for each index of each column family */
public class DataTracker
{
    private static final Logger logger = LoggerFactory.getLogger(DataTracker.class);

    private final AbstractType<?> keyValidator;
    private final ColumnIndex columnIndex;
    private final AtomicReference<View> view = new AtomicReference<>();

    public DataTracker(AbstractType<?> keyValidator, ColumnIndex index)
    {
        this.keyValidator = keyValidator;
        this.columnIndex = index;
        this.view.set(new View(index, Collections.<SSTableIndex>emptySet()));
    }

    public View getView()
    {
        return view.get();
    }

    /**
     * Replaces old SSTables with new by creating new immutable tracker.
     *
     * @param oldSSTables A set of SSTables to remove.
     * @param newSSTables A set of SSTables to add to tracker.
     *
     * @return A collection of SSTables which don't have component attached for current index.
     */
    public Iterable<SSTableReader> update(Collection<SSTableReader> oldSSTables, Collection<SSTableReader> newSSTables)
    {
        final Pair<Set<SSTableIndex>, Set<SSTableReader>> built = getBuiltIndexes(newSSTables);
        final Set<SSTableIndex> newIndexes = built.left;
        final Set<SSTableReader> indexedSSTables = built.right;

        View currentView, newView;
        do
        {
            currentView = view.get();
            newView = new View(columnIndex, currentView.getIndexes(), oldSSTables, newIndexes);
        }
        while (!view.compareAndSet(currentView, newView));

        return newSSTables.stream().filter(sstable -> !indexedSSTables.contains(sstable)).collect(Collectors.toList());
    }

    public boolean hasSSTable(SSTableReader sstable)
    {
        View currentView = view.get();
        for (SSTableIndex index : currentView)
        {
            if (index.getSSTable().equals(sstable))
                return true;
        }

        return false;
    }

    public void dropData(Collection<SSTableReader> sstablesToRebuild)
    {
        View currentView = view.get();
        if (currentView == null)
            return;

        Set<SSTableReader> toRemove = new HashSet<>(sstablesToRebuild);
        for (SSTableIndex index : currentView)
        {
            SSTableReader sstable = index.getSSTable();
            if (!sstablesToRebuild.contains(sstable))
                continue;

            index.markObsolete();
        }

        update(toRemove, Collections.<SSTableReader>emptyList());
    }

    public void dropData(long truncateUntil)
    {
        View currentView = view.get();
        if (currentView == null)
            return;

        Set<SSTableReader> toRemove = new HashSet<>();
        for (SSTableIndex index : currentView)
        {
            SSTableReader sstable = index.getSSTable();
            if (sstable.getMaxTimestamp() > truncateUntil)
                continue;

            index.markObsolete();
            toRemove.add(sstable);
        }

        update(toRemove, Collections.<SSTableReader>emptyList());
    }

    private Pair<Set<SSTableIndex>, Set<SSTableReader>> getBuiltIndexes(Collection<SSTableReader> sstables)
    {
        Set<SSTableIndex> indexes = new HashSet<>(sstables.size());
        Set<SSTableReader> builtSSTables = new HashSet<>(sstables.size());
        for (SSTableReader sstable : sstables)
        {
            if (sstable.isMarkedCompacted())
                continue;

            File indexFile = new File(sstable.descriptor.filenameFor(columnIndex.getComponent()));
            if (!indexFile.exists())
                continue;

            // if the index file is empty, we have to ignore it to avoid re-building, but it doesn't take
            // a part in query process
            if (indexFile.length() == 0)
            {
                builtSSTables.add(sstable);
                continue;
            }

            SSTableIndex index = null;

            try
            {
                index = new SSTableIndex(columnIndex, indexFile, sstable);

                logger.info("SSTableIndex.open(column: {}, minTerm: {}, maxTerm: {}, minKey: {}, maxKey: {}, sstable: {})",
                            columnIndex.getColumnName(),
                            columnIndex.getValidator().getString(index.minTerm()),
                            columnIndex.getValidator().getString(index.maxTerm()),
                            keyValidator.getString(index.minKey()),
                            keyValidator.getString(index.maxKey()),
                            index.getSSTable());

                // Try to add new index to the set, if set already has such index, we'll simply release and move on.
                // This covers situation when sstable collection has the same sstable multiple
                // times because we don't know what kind of collection it actually is.
                if (indexes.add(index))
                    builtSSTables.add(sstable);
                else
                    index.release();
            }
            catch (Throwable t)
            {
                logger.error("Can't open index file at " + indexFile.getAbsolutePath() + ", skipping.", t);
                if (index != null)
                    index.release();
            }
        }

        return Pair.create(indexes, builtSSTables);
    }
}
