/*
 * 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.control.nc.partitions;

import java.nio.ByteBuffer;
import java.util.ArrayDeque;
import java.util.Queue;

import edu.uci.ics.hyracks.api.channels.IInputChannel;
import edu.uci.ics.hyracks.api.channels.IInputChannelMonitor;
import edu.uci.ics.hyracks.api.comm.IFrameWriter;
import edu.uci.ics.hyracks.api.context.IHyracksRootContext;
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.api.partitions.IPartition;
import edu.uci.ics.hyracks.api.partitions.PartitionId;

public class MaterializedPartitionInputChannel implements IInputChannel {
    private final Queue<ByteBuffer> emptyQueue;

    private final Queue<ByteBuffer> fullQueue;

    private final PartitionId pid;

    private final PartitionManager manager;

    private final FrameWriter writer;

    private IInputChannelMonitor monitor;

    private Object attachment;

    public MaterializedPartitionInputChannel(IHyracksRootContext ctx, int nBuffers, PartitionId pid,
            PartitionManager manager) {
        this.emptyQueue = new ArrayDeque<ByteBuffer>(nBuffers);
        for (int i = 0; i < nBuffers; ++i) {
            emptyQueue.add(ctx.allocateFrame());
        }
        fullQueue = new ArrayDeque<ByteBuffer>(nBuffers);
        this.pid = pid;
        this.manager = manager;
        writer = new FrameWriter();
    }

    @Override
    public void registerMonitor(IInputChannelMonitor monitor) {
        this.monitor = monitor;
    }

    @Override
    public void setAttachment(Object attachment) {
        this.attachment = attachment;
    }

    @Override
    public Object getAttachment() {
        return attachment;
    }

    @Override
    public ByteBuffer getNextBuffer() {
        return fullQueue.poll();
    }

    @Override
    public void recycleBuffer(ByteBuffer buffer) {
        buffer.clear();
        synchronized (this) {
            emptyQueue.add(buffer);
            notifyAll();
        }
    }

    @Override
    public void open() throws HyracksDataException {
        IPartition partition = manager.getPartition(pid);
        partition.writeTo(writer);
    }

    @Override
    public void close() throws HyracksDataException {

    }

    private class FrameWriter implements IFrameWriter {
        @Override
        public void open() throws HyracksDataException {

        }

        @Override
        public void nextFrame(ByteBuffer buffer) throws HyracksDataException {
            synchronized (MaterializedPartitionInputChannel.this) {
                while (emptyQueue.isEmpty()) {
                    try {
                        MaterializedPartitionInputChannel.this.wait();
                    } catch (InterruptedException e) {
                        throw new HyracksDataException(e);
                    }
                }
                ByteBuffer destFrame = emptyQueue.poll();
                buffer.position(0);
                buffer.limit(buffer.capacity());
                destFrame.clear();
                destFrame.put(buffer);
                fullQueue.add(destFrame);
                monitor.notifyDataAvailability(MaterializedPartitionInputChannel.this, 1);
            }
        }

        @Override
        public void fail() throws HyracksDataException {

        }

        @Override
        public void close() throws HyracksDataException {
            monitor.notifyEndOfStream(MaterializedPartitionInputChannel.this);
        }
    }
}