package jp.hasc.hasctool.core.runtime.filter.file.label;

import java.util.TreeMap;

import jp.hasc.hasctool.core.data.LabelInfo;
import jp.hasc.hasctool.core.data.LabelSignalMessage;
import jp.hasc.hasctool.core.data.SignalMessage;
import jp.hasc.hasctool.core.runtime.filter.AbstractFilter;
import jp.hasc.hasctool.core.util.CSVUtil;


/**
 * LabelMessageを、CSVの文字列系列として出力するフィルタです。
 * 現在の実装では、出力される行は、ラベルの終了時刻順に並びます。
 * @author iwasaki
 */
public class LabelToCSVFilter extends AbstractFilter {
	/** logger for this class */
	private final static org.apache.commons.logging.Log LOG = org.apache.commons.logging.LogFactory
			.getLog(LabelToCSVFilter.class);
	
	private TreeMap<LabelInfo, LabelSignalMessage> currentBeginnningLabels_=new TreeMap<LabelInfo, LabelSignalMessage>();

	@Override
	public void processMessage(Object message) throws InterruptedException {
		if (message instanceof LabelSignalMessage) {
			LabelSignalMessage sig = (LabelSignalMessage) message;
			LabelInfo li = sig.getLabelInfo();
			switch(sig.getType()) {
			
			case BEGIN:
				if (currentBeginnningLabels_.containsKey(li)) throw new RuntimeException("duplicate BeginMessage for: "+li);
				currentBeginnningLabels_.put(li, sig);
				break;
				
			case END:
				LabelSignalMessage beginSig=currentBeginnningLabels_.get(li);
				if (beginSig==null) throw new RuntimeException("EndMessage without BeginMessage for: "+li);
				currentBeginnningLabels_.remove(li);
				// output CSV row
				outputMessage(CSVUtil.toCSVRecord(
						Double.toString(SignalMessage.TIME_UNIT.toMicros(beginSig.getTime())/1000000.0),
						Double.toString(SignalMessage.TIME_UNIT.toMicros(sig.getTime())/1000000.0),
						li.getRawLabel()
						));
				break;
				
			default:
				throw new RuntimeException();
			}
			
		}else if (message==SignalMessage.END) {
			if (!currentBeginnningLabels_.isEmpty()) {
				LOG.warn("labels doesn't ended: "+ currentBeginnningLabels_.keySet().toString());
			}
			outputMessage(message);
			
		}else if (message instanceof SignalMessage) {
			// NOP
		}else{
			outputMessage(message);
		}
	}

}
