/*
 * Copyright 2009-2012 by The Regents of the University of California
 * Licensed 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 from
 * 
 *     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 edu.uci.ics.hyracks.storage.am.lsm.invertedindex.ondisk;

import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
import edu.uci.ics.hyracks.storage.am.btree.impls.RangePredicate;
import edu.uci.ics.hyracks.storage.am.common.api.ICursorInitialState;
import edu.uci.ics.hyracks.storage.am.common.api.IIndexAccessor;
import edu.uci.ics.hyracks.storage.am.common.api.IIndexCursor;
import edu.uci.ics.hyracks.storage.am.common.api.IIndexOperationContext;
import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
import edu.uci.ics.hyracks.storage.am.common.impls.NoOpOperationCallback;
import edu.uci.ics.hyracks.storage.am.common.tuples.ConcatenatingTupleReference;
import edu.uci.ics.hyracks.storage.am.common.tuples.PermutingTupleReference;
import edu.uci.ics.hyracks.storage.am.lsm.invertedindex.api.IInvertedIndex;
import edu.uci.ics.hyracks.storage.am.lsm.invertedindex.api.IInvertedListCursor;

/**
 * Scans a range of tokens, returning tuples containing a token and an inverted-list element.
 */
public class OnDiskInvertedIndexRangeSearchCursor implements IIndexCursor {

    private final BTree btree;
    private final IIndexAccessor btreeAccessor;
    private final IInvertedIndex invIndex;
    private final IIndexOperationContext opCtx;
    private final IInvertedListCursor invListCursor;
    private boolean unpinNeeded;
    
    private final IIndexCursor btreeCursor;
    private RangePredicate btreePred;

    private final PermutingTupleReference tokenTuple;
    private ConcatenatingTupleReference concatTuple;

    public OnDiskInvertedIndexRangeSearchCursor(IInvertedIndex invIndex, IIndexOperationContext opCtx) {
        this.btree = ((OnDiskInvertedIndex) invIndex).getBTree();
        this.btreeAccessor = btree.createAccessor(NoOpOperationCallback.INSTANCE, NoOpOperationCallback.INSTANCE);
        this.invIndex = invIndex;
        this.opCtx = opCtx;
        // Project away non-token fields of the BTree tuples.
        int[] fieldPermutation = new int[invIndex.getTokenTypeTraits().length];
        for (int i = 0; i < invIndex.getTokenTypeTraits().length; i++) {
            fieldPermutation[i] = i;
        }
        tokenTuple = new PermutingTupleReference(fieldPermutation);
        btreeCursor = btreeAccessor.createSearchCursor();
        concatTuple = new ConcatenatingTupleReference(2);
        invListCursor = invIndex.createInvertedListCursor();
        unpinNeeded = false;
    }

    @Override
    public void open(ICursorInitialState initialState, ISearchPredicate searchPred) throws HyracksDataException, IndexException {
        this.btreePred = (RangePredicate) searchPred;
        try {
            btreeAccessor.search(btreeCursor, btreePred);
        } catch (IndexException e) {
            throw new HyracksDataException(e);
        }        
        invListCursor.pinPages();
        unpinNeeded = true;
    }

    @Override
    public boolean hasNext() throws HyracksDataException, IndexException {
        if (invListCursor.hasNext()) {
            return true;
        }
        if (unpinNeeded) {
            invListCursor.unpinPages();
            unpinNeeded = false;
        }
        if (!btreeCursor.hasNext()) {
            return false;
        }
        btreeCursor.next();
        tokenTuple.reset(btreeCursor.getTuple());
        try {
            invIndex.openInvertedListCursor(invListCursor, tokenTuple, opCtx);
        } catch (IndexException e) {
            throw new HyracksDataException(e);
        }
        invListCursor.pinPages();
        invListCursor.hasNext();
        unpinNeeded = true;
        concatTuple.reset();
        concatTuple.addTuple(tokenTuple);
        return true;
    }

    @Override
    public void next() throws HyracksDataException {
        invListCursor.next();
        if (concatTuple.hasMaxTuples()) {
            concatTuple.removeLastTuple();
        }
        concatTuple.addTuple(invListCursor.getTuple());
    }

    @Override
    public void close() throws HyracksDataException {
        if (unpinNeeded) {
            invListCursor.unpinPages();
            unpinNeeded = false;
        }
        btreeCursor.close();
    }

    @Override
    public void reset() throws HyracksDataException, IndexException {
        if (unpinNeeded) {
            invListCursor.unpinPages();
            unpinNeeded = false;
        }
        btreeCursor.close();
    }

    @Override
    public ITupleReference getTuple() {
        return concatTuple;
    }
}
