/*
 * 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.fukurou.transfer;

import org.opengion.fukurou.db.DBUtil;
import org.opengion.fukurou.db.Transaction;
import org.opengion.fukurou.util.StringUtil;
import org.opengion.fukurou.util.HybsDateUtil;

/**
 * 伝送要求に対して旧伝送DB(CB01)に登録を行います。
 *
 * 旧伝送DB登録時のデータコード、送り先、テキスト種別は、伝送定義マスタの実行対象で指定します。
 * 具体的には以下の形式で定義します。
 *   (データコード) (送り先) (テキスト種別) [(レコード長)] 例):"3 D9 B119 [400]"
 * 4番目のパラメーターであるレコード長は任意です。レコード長が指定されない場合、
 * デフォルト値として 400 が定義されます。
 *
 * CB01の各項目のセット基準は以下の通りです。
 *
 *						ヘッダーデータ		明細データ
 *  ---------------------------------------------------
 *  HCDJ(状況)			1					5
 *  HCDD(カードコード)	[実行対象]			[実行対象]
 *  HTO(送り先)			[実行対象]			[実行対象]
 *  HSYU(テキスト種別)	[実行対象]			[実行対象]
 *  HLDAY(登録日)		システム日付		システム日付
 *  HLTIME(登録時間)	システム日付		システム日付
 *  HDPDAY(削除日)		システム日付+14日	システム日付+14日
 *  HFROM(送り元)		[システムリソース]	[システムリソース]	※TRANSFER_HOST_CODEの値
 *  HTCNO(通番NO)		CB010001.NEXTVAL	CB010001.NEXTVAL
 *  HTC(通番)			CB010002.NEXTVAL	CB010002.NEXTVAL
 *  HTEXT(データ)		送り先+登録件数		データ
 *  DYUNYOU(運用日)		CJ03.DYUNYOU		CJ03.DYUNYOU
 *  RECL(レコード長)	[実行対象]			[実行対象]			※初期値400
 *
 *  この_CB01を利用する場合CB01テーブル以外に次のテーブル及びシーケンスが必要です
 *  テーブル：CB02
 *  シーケンス：CB010001,CB010002
 *
 * @og.rev 5.4.4.1 コメント修正
 * @og.rev 5.5.7.3 CB01登録時のHPASS,HNAME変更
 * @og.group 伝送システム
 *
 * @version  5.0
 * @author   Hiroki.Nakamura
 * @since    JDK1.6
 */
public class TransferExec_CB01 implements TransferExec {

	// 旧伝送DB(CB01)登録
	// 5.5.7.3 (2012/10/12) HPASS,HNAMEがnullでは駄目なのでスペース
	private static final String CB01_INSERT =
		"INSERT INTO CB01 ("
		+ "HCDJ,HCDD,HTO,HSYU,HLDAY,HLTIME,HDPDAY,HTEXT1,HTEXT2"
		+ ",HPASS,HFROM,HNAME,HTCNO,HTC,HTEXT,DYUNYOU,RECL"
		+ ") VALUES ("
		+ "?,?,?,?,?,?,?,null,null"
		+ ",'        ',?,'                    ',?,?,?,?,?"
		+ ")";

	// 通番NO取得
	private static final String HTCNO_GET = "SELECT CB010001.NEXTVAL FROM DUAL";

	// 通番取得
	private static final String HTC_GET = "SELECT CB010002.NEXTVAL FROM DUAL";

	// 運用日取得
	private static final String DYUNYOU_GET = "SELECT DYUNYOU FROM CJ03";

	// 削除日付基準日数
	private static final int HDAY = 14;

	// レコード長の初期値
	private static final String DEFAULT_RECL = "400";

	/**
	 * CB01に登録します。
	 *
	 * @og.rev 5.5.7.2 (2012/10/09) HybsDateUtil を利用するように修正します。
	 *
	 * @param vals 伝送データ(配列)
	 * @param config 伝送設定オブジェクト
	 * @param tran トランザクションオブジェクト
	 */
	@Override
	public void execute( final String[] vals, final TransferConfig config, final Transaction tran ) {
		if( vals == null || vals.length == 0 ) { return; }

		final String execObj = config.getExecObj();
		final String[] obj = StringUtil.csv2Array( execObj, ' ' );
		if( obj.length < 3 ) {
			final String errMsg = "実行対象は、(データコード) (送り先) (テキスト種別) の形式で指定して下さい。"
							+ "EXECOBJ=[" + execObj + "]";
			throw new RuntimeException( errMsg );
		}
		final String hcdd = obj[0];
		final String hto = obj[1];
		final String hsyu = obj[2];
		if( hcdd == null || hcdd.isEmpty()
		 || hto  == null || hto.isEmpty()
		 || hsyu == null || hsyu.isEmpty() ) {
			final String errMsg = "実行対象は、(データコード) (送り先) (テキスト種別) は必須です。"
							+ "EXECOBJ=[" + execObj + "]";
			throw new RuntimeException( errMsg );
		}
		final String recl = ( obj.length > 3 ) ? obj[3] : DEFAULT_RECL;

		final String execDbid = config.getExecDbid();

		final String htcno = getHtcno( tran, execDbid );
		final String hlday  = HybsDateUtil.getDate( "yyyyMMdd" );			// 5.5.7.2 (2012/10/09) HybsDateUtil を利用
		final String hltime = HybsDateUtil.getDate( "HHmm" );				// 5.5.7.2 (2012/10/09) HybsDateUtil を利用
		final String hdpday = HybsDateUtil.getDatePlus( hlday, HDAY );	// 5.5.7.2 (2012/10/09) HybsDateUtil を利用

		// ヘッダー行追加
		final String[] headerArgs = new String[] {
				"1",								// HCDJ
				hcdd ,								// HCDD
				hto,								// HTO
				hsyu,								// HSYU
				hlday.substring( 2 ),				// HLDAY
				hltime,								// HLTIME
				hdpday.substring( 2 ),				// HDPDAY
				config.getHfrom(),					// HFROM
				htcno,								// HTCNO
				getHtc( tran, execDbid ),			// HTC
				getHeaderText( hto, vals.length ),	// HTEXT
				getDyunyou( tran, execDbid ),		// DYUNYOU
				recl								// RECL
			};
		DBUtil.dbExecute( CB01_INSERT, headerArgs, tran, execDbid );

		// 明細行追加
		for( final String text : vals ) {
			final String[] dataArgs = new String[] {
					"5",								// HCDJ
					hcdd ,								// HCDD
					hto,								// HTO
					hsyu,								// HSYU
					hlday.substring( 2 ),				// HLDAY
					hltime,								// HLTIME
					hdpday.substring( 2 ),				// HDPDAY
					config.getHfrom(),					// HFROM
					htcno,								// HTCNO
					getHtc( tran, execDbid ),			// HTC
					text,								// HTEXT
					getDyunyou( tran, execDbid ),		// DYUNYOU
					recl								// RECL
				};
			DBUtil.dbExecute( CB01_INSERT, dataArgs, tran, execDbid );
		}
	}

	/**
	 * ヘッダーデータのテキストを返します。
	 * (CSP00007と同じ仕様で実装)
	 *
	 * @param hto 送り先
	 * @param cnt 登録件数
	 *
	 * @return ヘッダーデータのテキスト
	 * @og.rtnNotNull
	 */
	private static String getHeaderText( final String hto, final int cnt ) {
		return StringUtil.stringFill( hto, 8, "UTF-8" )
						+ " 登録件数 = " + cnt;
	}

	/**
	 * 通番NOを採番します。
	 * (CSP00007と同じ仕様で実装)
	 *
	 * @param tran トランザクションオブジェクト
	 * @param execDbid 実行接続先DBID
	 *
	 * @return 通番NO
	 */
	private static String getHtcno( final Transaction tran, final String execDbid ) {
		final String[][] rtn = DBUtil.dbExecute( HTCNO_GET, new String[0], tran, execDbid );
		return rtn[0][0];
	}

	/**
	 * 通番を採番します。
	 * (CSP00007と同じ仕様で実装)
	 *
	 * @param tran トランザクションオブジェクト
	 * @param execDbid 実行接続先DBID
	 *
	 * @return 通番
	 */
	private static String getHtc( final Transaction tran, final String execDbid ) {
		final String[][] rtn = DBUtil.dbExecute( HTC_GET, new String[0], tran, execDbid );
		return rtn[0][0];
	}

	/**
	 * 運用日を取得します。(CJ03>運用日)
	 * (CSP00007と同じ仕様で実装)
	 *
	 * @param tran トランザクションオブジェクト
	 * @param execDbid 実行接続先DBID
	 *
	 * @return 運用日
	 */
	private static String getDyunyou( final Transaction tran, final String execDbid ) {
		final String[][] rtn = DBUtil.dbExecute( DYUNYOU_GET, new String[0], tran, execDbid );
		return rtn[0][0];
	}
}
