package jp.ne.mki.wedge.sample.client.log;

import java.util.logging.LogRecord;
import java.util.logging.SimpleFormatter;
import jp.ne.mki.wedge.common.library.HashVector;
import jp.ne.mki.wedge.rule.base.AbstractClient;
import jp.ne.mki.wedge.run.client.control.log.EndRuleLogRecord;
import jp.ne.mki.wedge.run.client.control.log.EndTranLogRecord;
import jp.ne.mki.wedge.run.client.control.log.FrameTransLogRecord;
import jp.ne.mki.wedge.run.client.control.log.StartRuleLogRecord;
import jp.ne.mki.wedge.run.client.control.log.StartTranLogRecord;
import jp.ne.mki.wedge.run.client.control.log.TimeLogRecord;
import jp.ne.mki.wedge.run.client.data.Item;
import jp.ne.mki.wedge.run.interfaces.RuleEngineInterface;

/**
 * <h2>アイテム名称出力フォーマッタ</h2>
 * <p>
 * ビジネスルール入出力引数の論理名も出力するフォーマッタです。 <br>
 * 
 * <pre>
 * 
 *   ■BusinessRule START-------------------------------------------- 
 *   FRAME_NAME:フレーム実行＆画面遷移テスト(FrameRunner(CSV))
 *   NAME: ReadCsvFileToItem &lt;ReadCsvFileToItem&gt;
 *   CLASS: jp.ne.mki.wedge.rule.common.file.ReadCsvFileToItem
 *   PARAM: [-encoding SJIS]
 *   TARGET: Frame(フレーム実行＆画面遷移テスト) 
 *   TIMING: LOAD
 *   INPUT RECORD ( 1 )
 *    【共通領域Dr】memDir	[./mem.csv]
 *   
 *   RESULT:OK
 *   OUTPUT RECORD ( 2 )
 *    【共有領域キー】Key	[key1],[key2]
 *    【共有領域値】Data	[1000],[2000]
 *  -------------------------------------------------------------------------
 *  
 * </pre>
 * 
 * </p>
 * 
 * <h3>使用にあたって</h3>
 * <p>
 * このクラスはサンプル提供のクラスです。 <br>
 * そのままお使い頂く事/修正して使用して頂く事 は可能ですが、
 *  サポート対象外とさせて頂きます。 <br>
 * 独自でクラス作成する際の参考資料としてお使いください。
 * </p>
 * 
 * @author Media Knowlege Industrial Co.,Ltd.
 * @since webtribe/visualframe ver1.1.0
 */
public class ItemNameFormatter extends SimpleFormatter {
    /**
     * フォーマット
     * @param record 出力のログレコード
     * @return String 出力文字列
     */
    public final synchronized String format(final LogRecord record) {
        StringBuffer sb = new StringBuffer();
        // ビジネスルール開始レコードの時
        if (record instanceof StartRuleLogRecord) {
            String message = formatMessage(record);
            sb.append("\n\r\n■");
            sb.append(message);
            sb.append("-------------------------------------------- ");
            StartRuleLogRecord rule = (StartRuleLogRecord) record;
            sb.append("\r\n");
            sb.append("FRAME_NAME:").append(rule.getFrameLName()).append("(")
                    .append(rule.getFramePName()).append(")");
            sb.append("\r\n");
            sb.append("NAME: ").append(rule.getLogicallName()).append(" <")
                    .append(rule.getPhysicalName()).append(">");
            RuleEngineInterface ruleObj = rule.getRuleObject();
            if (ruleObj != null) {
                sb.append("\r\n");
                sb.append("CLASS: ").append(ruleObj.getClass().getName());
                sb.append("\r\n");
                sb.append("PARAM: [").append(ruleObj.getRuleParameter())
                        .append("]");
                if (ruleObj instanceof AbstractClient) {
                    sb.append("\r\n");
                    sb.append("ePARAM: [").append(
                            ((AbstractClient) ruleObj).getExecuteParameter())
                            .append("]");
                }
            } else {
                sb.append("\r\n");
                sb.append("TYPE:").append(rule.getRuleType());
            }
            sb.append("\r\n");
            sb.append("TARGET: ").append(rule.getTarget());
            sb.append("\r\n");
            sb.append("TIMING: ").append(rule.getTiming());
            HashVector inRecord = rule.getInRecord();
            sb.append("\r\n");
            sb.append("INPUT RECORD ( ").append(inRecord.size()).append(" )");
            writeItemRecord(inRecord, sb);
            sb.append("\r\n");
            //ビジネスルール終了レコードの時
        } else if (record instanceof EndRuleLogRecord) {
            EndRuleLogRecord rule = (EndRuleLogRecord) record;
            sb.append("\r\n");
            sb.append("RESULT:").append(rule.getResult());
            HashVector outRecord = rule.getOutRecord();
            sb.append("\r\n");
            sb.append("OUTPUT RECORD ( ").append(outRecord.size()).append(" )");
            writeItemRecord(outRecord, sb);
            sb.append("\r\n");
            sb.append("-------------------------------------------------------------------------\r\n\r\n");
            // トランザクション開始レコードの時
        } else if (record instanceof StartTranLogRecord) {
            String message = formatMessage(record);
            sb.append("\r\n■");
            sb.append(message).append("-------------------");
            StartTranLogRecord tran = (StartTranLogRecord) record;
            sb.append("\r\n");
            sb.append("FRAME_NAME:").append(tran.getFrameLName()).append("(")
                    .append(tran.getFramePName()).append(")");
            sb.append("\r\n");
            sb.append("NAME:").append(tran.getLogicalName());
            sb.append("\r\n");
            sb.append("PNAME:").append(tran.getPhysicalName());
            sb.append("\r\n");
            sb.append("SERVER SUB:").append(tran.getServerSubName());
            sb.append("\r\n");
            sb.append("SERVER TRAN:").append(tran.getTransactionName());
            sb.append("\r\n");
            sb.append("SERVER REV:").append(tran.getServerSubRevision());
            sb.append("\r\n");
            sb.append("TARGET:").append(tran.getTarget());
            sb.append("\r\n");
            sb.append("TIMING:").append(tran.getTiming());
            HashVector inRecord = tran.getInRecord();
            sb.append("\r\n");
            sb.append("INPUT RECORD ( ").append(inRecord.size()).append(" )");
            writeItemRecord(inRecord, sb);
            sb.append("\r\n");
            // トランザクション終了レコードの時
        } else if (record instanceof EndTranLogRecord) {
            EndTranLogRecord tran = (EndTranLogRecord) record;
            sb.append("\r\n");
            sb.append("RESULT:").append(tran.getResult());
            sb.append("\r\n");
            sb.append("SERVER_PARAM:").append(tran.getServerParameter());
            sb.append("\r\n");
            sb.append("SERVER_MESSAGE:").append(tran.getServerDetailMessage());
            HashVector outRecord = tran.getOutRecord();
            sb.append("\r\n");
            sb.append("OUTPUT RECORD ( ").append(outRecord.size()).append(" )");
            writeItemRecord(outRecord, sb);
            sb.append("\r\n");
            sb.append("-------------------------------------------------------------------------\r\n");
            //画面遷移レコード
        } else if (record instanceof FrameTransLogRecord) {
            FrameTransLogRecord trans = (FrameTransLogRecord) record;
            sb.append("\r\n");
            sb.append("  ---- FRAME TRANSFER DATA-------");
            int size = trans.getSize();
            for (int i = 0; i < size; i++) {
                sb.append("\r\n");
                Object[] datas = trans.getTransData(i);
                Item fromItem = (Item) datas[0];
                Item toItem = (Item) datas[1];
                sb.append(fromItem.getPhysicalName()).append("[").append(
                        datas[2]).append("]").append("→").append(
                        toItem.getPhysicalName());
                if (!datas[4].equals("true")) {
                    sb.append("[").append(datas[3]).append("]");
                }
            }
            sb.append("\r\n");
            sb.append(" -------------------------------------------------------------------------\r\n");
            //タイムログレコード
        } else if (record instanceof TimeLogRecord) {
            TimeLogRecord time = (TimeLogRecord) record;
            sb.append("[").append(record.getMessage()).append(" time]").append(
                    time.getTargetName());
            if (time.getEventName() != null) {
                sb.append("/").append(time.getEventName());
            }
            sb.append(" :").append(time.getTime()).append(" m/s \r\n");
            // Throwable付きの場合にはSimpleFomatterそのままのメッセージ出力
        } else if (record.getThrown() != null) {
            String message = super.format(record);
            sb.append(message);
        } else {
            String message = formatMessage(record);
            sb.append(message);
        }
        return sb.toString();
    }

    /**
     * データレコード出力
     * @param record レコード
     * @param sb 出力バッファ
     */
    private void writeItemRecord(final HashVector record, final StringBuffer sb) {
        int recordSize = record.size();
        for (int i = 0; i < recordSize; i++) {
            Item item = (Item) record.get(i);
            sb.append("\r\n");
            sb.append(" 【").append(item.getLogicalName()).append("】").append(
                    item.getInformation());
        }
    }
}
