package jp.hasc.hasctool.core.runtime.hierarchize;

import java.util.ArrayList;

import jp.hasc.hasctool.core.data.EnumCommand;
import jp.hasc.hasctool.core.messaging.MessageProcessor;
import jp.hasc.hasctool.core.messaging.MessageQueue;
import jp.hasc.hasctool.core.runtime.RuntimeContext;
import jp.hasc.hasctool.core.runtime.source.AbstractSource;

/**
 * 複数のポートから入力されたメッセージ系列を、ポートインデックス順に単純に追加し、単一のメッセージ系列として出力します。
 * 例えば、ポート0から BEGIN,A,B,END、ポート1から BEGIN,C,D,END というメッセージ系列が入力された場合、BEGIN,A,B,C,D,END という系列を出力します。
 * 多入力、１出力のブロックです。
 * 入力ポートの数を、inputPortプロパティで指定して下さい。
 * @author iwasaki
 */
public class MessageAppender extends AbstractSource {
	// それぞれの入力はキューに積まれ、それを別スレッドから取り出して処理される
	protected ArrayList<MessageQueue> inputPorts_=new ArrayList<MessageQueue>();
	
	private int inputPortCount_;
	
	public int getInputPortCount() {
		return inputPortCount_;
	}
	
	/**
	 * 入力ポートの数を指定します。
	 */
	public void setInputPortCount(int size) {
		inputPortCount_=size;
	}
	
	/**
	 * 指定したインデックスの入力ポートを返します。
	 */
	public MessageProcessor getInputPort(int index) {
		return inputPorts_.get(index);
	}
	
	public MessageQueue createMessageQueue(int portIndex) {
		return getRuntimeContext().createDefaultMessageQueue();
	}
	
	@Override
	public void setup(RuntimeContext context) {
		super.setup(context);
		
		// create input ports
		inputPorts_.clear();
		for(int i=0;i<inputPortCount_;++i) {
			inputPorts_.add(createMessageQueue(i));
		}
	}
	
	@Override
	protected void run() throws InterruptedException {
		int psize = getInputPortCount();
		outputMessage(EnumCommand.BEGIN);
		for(int i=0;i<psize;++i) {
			MessageQueue queue = inputPorts_.get(i);
			while(!isShutdown()) {
				Object message = queue.readMessage();
				if (message==EnumCommand.BEGIN) {
					// NOP
				}else if (message==EnumCommand.END) {
					break;
				}else{
					outputMessage(message);
				}
			}
		}
		outputMessage(EnumCommand.END);
	}

}
