/*
 * Copyright (c) 2009 The openGion Project.
 *
 * 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 at
 *
 *     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 org.opengion.plugin.io;

import java.io.PrintWriter;

import org.opengion.fukurou.util.StringUtil;
import org.opengion.hayabusa.db.DBTableModel;

/**
 * TableWriter をJSON形式で出力する為の実装ｸﾗｽです。
 * DefaultTableWriter を継承していますので、ﾗﾍﾞﾙ、名前、ﾃﾞｰﾀの出力部のみ
 * ｵｰﾊﾞｰﾗｲﾄﾞして、JSON形式ﾌｧｲﾙの出力機能を実現しています。
 *
 * 出力のJSON形式(JavaScript Object Notation)は、通常版ではなく IOｒ形式のJSONです。
 *
 * {
 *   "status": 200,
 *   "message": "OK",
 *   "sessionInfo": "",
 *   "information": "",
 *   "data": {
 *     "headers": [
 *       { "display_label": "品目番号","display": "PN"     },
 *       { "display_label": "入出庫数","display": "SUNYSY" },
 *     ],
 *     "rows": [
 *       {"cols": [ "100-1A100-01", "T", 1,00+00"  ]},
 *       {"cols": [ "200-2A125-01", "T", 500,00+00"]},
 *       {"cols": [ "100-1A100-01", "T", 100,00+00"]},
 *       {"cols": [ "200-2A125-01", "T", 200,00+00"]}
 *     ]
 *   }
 * }
 *
 *
 * @og.rev 8.1.1.0 (2022/02/04) 新規作成
 * @og.group ﾌｧｲﾙ出力
 *
 * @version  8.1
 * @author   Kazuhiko Hasegawa
 * @since    JDK17,
 */
public class TableWriter_JSON2 extends TableWriter_Default {
	/** このﾌﾟﾛｸﾞﾗﾑのVERSION文字列を設定します。	{@value} */
	private static final String VERSION = "8.1.1.0 (2022/02/04)" ;

	private static final String INFO = " \"status\":200,\"message\":\"OK\",\"sessionInfo\":\"\",\"information\":\"\"," ;

	/**
	 * ﾃﾞﾌｫﾙﾄｺﾝｽﾄﾗｸﾀｰ
	 */
	public TableWriter_JSON2() { super(); }		// これも、自動的に呼ばれるが、空のﾒｿｯﾄﾞを作成すると警告されるので、明示的にしておきます。

	/**
	 * DBTableModel から ﾃﾞｰﾀを作成して、PrintWriter に書き出します。
	 *
	 * @param	writer PrintWriterｵﾌﾞｼﾞｪｸﾄ
	 */
	@Override
	public void writeDBTable( final PrintWriter writer )  {
		writer.println( "{" );
		writer.println( INFO );
		writer.println( " \"data\":{\"" );

		super.setHeaderSequence( "LD" );
		super.writeDBTable( writer );

		writer.println( " }" );
		writer.println( "}" );
	}

	/**
	 * PrintWriter に DBTableModelのラベル情報を書き込みます。
	 *
	 * IORのﾍｯﾀﾞｰ情報は、
	 *   "headers":[{"display_label":"≪ｶﾗﾑﾗﾍﾞﾙ≫","display":"≪ｶﾗﾑ≫",},…,],
	 * 形式です。
	 *
	 * @param	table DBTableModelオブジェクト
	 * @param	writer PrintWriterオブジェクト
	 */
	@Override
	protected void writeLabel( final DBTableModel table,final PrintWriter writer ) {
		writer.println( "  \"headers\":[" );

		for( int i=0; i<numberOfColumns; i++ ) {
			final int clm = clmNo[i];
			if( clm < 0 ) { continue; }			// カラム飛ばし
			final String val = StringUtil.tagCut( dbColumn[clm].getLabel() );
			writer.print( "   {\"display_label\":\"" );
			writer.print( val );
			writer.print( "\",\"display\":\"" );
			writer.print( dbColumn[clm].getName() );
			writer.println( "\"}," );
		}
		writer.println( "  ]," );
	}

	/**
	 * PrintWriter に DBTableModelのﾃｰﾌﾞﾙ情報を書き込みます。
	 *
	 * IORのﾃﾞｰﾀ情報は、
	 *   "rows": [
	 *     {"cols": [ "≪ﾃﾞｰﾀ1≫", "≪ﾃﾞｰﾀ2≫",…]},
	 *     {"cols": [ "≪ﾃﾞｰﾀ1≫", "≪ﾃﾞｰﾀ2≫",…]},
	 *   ]
	 * 形式です。
	 *
	 * @param	table  DBTableModelｵﾌﾞｼﾞｪｸﾄ
	 * @param	writer PrintWriterｵﾌﾞｼﾞｪｸﾄ
	 */
	@Override
	protected void writeData( final DBTableModel table,final PrintWriter writer ) {
		final int numberOfRows =  table.getRowCount();

		writer.println( "  \"rows\":[" );

		final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE );	// \(ﾊﾞｯｸｽﾗｯｼｭ) と "(ﾀﾞﾌﾞﾙｸｵｰﾄ)のｴｽｹｰﾌﾟ 処理用
		for( int row=0; row<numberOfRows; row++ ) {
			writer.print( "   {\"cols\":[" );
			for( int i=0; i<numberOfColumns; i++ ) {
				final int clm = clmNo[i];
				if( clm < 0 ) { continue; }			// ｶﾗﾑ飛ばし

				String val = table.getValue(row,clm);
				// \(ﾊﾞｯｸｽﾗｯｼｭ) と "(ﾀﾞﾌﾞﾙｸｵｰﾄ)のｴｽｹｰﾌﾟ
				if( val.contains( "\\" ) || val.contains( "\"" ) ) {
					buf.setLength(0);
					for( int j=0; j<val.length(); j++ ) {
						final char ch = val.charAt( j );
						if( ch == '\\' || ch == '\"' ) { buf.append( '\\' ); }
						buf.append( ch );
					}
					val = buf.toString();
				}

				writer.print( '"' );
				writer.print( val );
				writer.print( "\"," );
			}
			writer.println( "]}," );
		}

		writer.println( "  ]" );
	}
}
