/*
 * Copyright 2009-2010 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.search;

import java.nio.ByteBuffer;
import java.util.ArrayList;

import edu.uci.ics.hyracks.api.context.IHyracksCommonContext;
import edu.uci.ics.hyracks.api.dataflow.value.ITypeTraits;
import edu.uci.ics.hyracks.data.std.primitive.IntegerPointable;
import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
import edu.uci.ics.hyracks.storage.am.lsm.invertedindex.ondisk.FixedSizeFrameTupleAccessor;
import edu.uci.ics.hyracks.storage.am.lsm.invertedindex.ondisk.FixedSizeFrameTupleAppender;
import edu.uci.ics.hyracks.storage.am.lsm.invertedindex.ondisk.FixedSizeTupleReference;

/**
 * Byte-buffer backed storage for intermediate and final results of inverted-index searches.
 */
// TODO: Rename members.
public class SearchResult {
    protected final ArrayList<ByteBuffer> buffers = new ArrayList<ByteBuffer>();
    protected final IHyracksCommonContext ctx;
    protected final FixedSizeFrameTupleAppender appender;
    protected final FixedSizeFrameTupleAccessor accessor;
    protected final FixedSizeTupleReference tuple;
    protected final ITypeTraits[] typeTraits;
    protected final int invListElementSize;

    protected int currBufIdx;
    protected int numResults;

    public SearchResult(ITypeTraits[] invListFields, IHyracksCommonContext ctx) {
        typeTraits = new ITypeTraits[invListFields.length + 1];
        int tmp = 0;
        for (int i = 0; i < invListFields.length; i++) {
            typeTraits[i] = invListFields[i];
            tmp += invListFields[i].getFixedLength();
        }
        invListElementSize = tmp;
        // Integer for counting occurrences.
        typeTraits[invListFields.length] = IntegerPointable.TYPE_TRAITS;
        this.ctx = ctx;
        appender = new FixedSizeFrameTupleAppender(ctx.getFrameSize(), typeTraits);
        accessor = new FixedSizeFrameTupleAccessor(ctx.getFrameSize(), typeTraits);
        tuple = new FixedSizeTupleReference(typeTraits);
        buffers.add(ctx.allocateFrame());
    }

    /**
     * Initialize from other search-result object to share member instances except for result buffers.
     */
    public SearchResult(SearchResult other) {
        this.ctx = other.ctx;
        this.appender = other.appender;
        this.accessor = other.accessor;
        this.tuple = other.tuple;
        this.typeTraits = other.typeTraits;
        this.invListElementSize = other.invListElementSize;
        buffers.add(ctx.allocateFrame());
    }

    public FixedSizeFrameTupleAccessor getAccessor() {
        return accessor;
    }

    public FixedSizeFrameTupleAppender getAppender() {
        return appender;
    }

    public FixedSizeTupleReference getTuple() {
        return tuple;
    }

    public ArrayList<ByteBuffer> getBuffers() {
        return buffers;
    }

    public void reset() {
        currBufIdx = 0;
        numResults = 0;
        appender.reset(buffers.get(0), true);
    }

    public void clear() {
        currBufIdx = 0;
        numResults = 0;
        for (ByteBuffer buffer : buffers) {
            appender.reset(buffer, true);
        }
    }

    public void append(ITupleReference invListElement, int count) {
        ByteBuffer currentBuffer = buffers.get(currBufIdx);
        if (!appender.hasSpace()) {
            currBufIdx++;
            if (currBufIdx >= buffers.size()) {
                buffers.add(ctx.allocateFrame());
            }
            currentBuffer = buffers.get(currBufIdx);
            appender.reset(currentBuffer, true);
        }
        // Append inverted-list element.
        if (!appender.append(invListElement.getFieldData(0), invListElement.getFieldStart(0), invListElementSize)) {
            throw new IllegalStateException();
        }
        // Append count.
        if (!appender.append(count)) {
            throw new IllegalStateException();
        }
        appender.incrementTupleCount(1);
        numResults++;
    }

    public int getCurrentBufferIndex() {
        return currBufIdx;
    }

    public ITypeTraits[] getTypeTraits() {
        return typeTraits;
    }

    public int getNumResults() {
        return numResults;
    }

    // TODO: This code may help to clean up the core list-merging algorithms.
    /*
    public SearchResultCursor getCursor() {
        cursor.reset();
        return cursor;
    }
    
    public class SearchResultCursor {
        private int bufferIndex;
        private int resultIndex;
        private int frameResultIndex;
        private ByteBuffer currentBuffer;

        public void reset() {
            bufferIndex = 0;
            resultIndex = 0;
            frameResultIndex = 0;
            currentBuffer = buffers.get(0);
            resultFrameTupleAcc.reset(currentBuffer);
        }

        public boolean hasNext() {
            return resultIndex < numResults;
        }

        public void next() {
            resultTuple.reset(currentBuffer.array(), resultFrameTupleAcc.getTupleStartOffset(frameResultIndex));            
            if (frameResultIndex < resultFrameTupleAcc.getTupleCount()) {
                frameResultIndex++;
            } else {
                bufferIndex++;
                currentBuffer = buffers.get(bufferIndex);
                resultFrameTupleAcc.reset(currentBuffer);
                frameResultIndex = 0;
            }            
            resultIndex++;
        }

        public ITupleReference getTuple() {
            return resultTuple;
        }
    }
    */
}
