package org.opengion.hayabusa.queue;

import org.opengion.fukurou.db.ConnectionFactory;
import org.opengion.fukurou.db.DBFunctionName;
import org.opengion.fukurou.db.DBUtil;
import org.opengion.fukurou.db.Transaction;
import org.opengion.fukurou.db.TransactionReal;
import org.opengion.fukurou.util.ApplicationInfo;
import org.opengion.fukurou.util.StringUtil;
import org.opengion.hayabusa.common.HybsSystem;

/**
 * キュー処理用のDBアクセスクラス
 * キューの受信と送信処理で、
 * データベースにアクセスして処理を行います。
 *
 * 実際のMQ,SQSとの通信そのものはfukurouで行います。
 * 
 * @og.group メッセージ連携
 *
 * @og.rev 5.10.15.2 (2019/09/20) 新規作成
 * 
 * @version 5
 * @author oota
 * @since JDK7
 *
 */
public class DBAccessQueue {
	private static final String DYSET_YMD  = "yyyyMMddHHmmss";
	private static  ApplicationInfo appInfo = null;
	private static final String DBID = HybsSystem.sys( "RESOURCE_DBID" );
	private final String SYSTEM_ID;
	private final String USRSET;
	private final String PGUPD;
	private final String DMN_NAME;
	
	// 処理中
	public static final String  FGKAN_PROCESS = "2";
	// 完了
	public static final String  FGKAN_END = "3";
	// エラー
	public static final String  FGKAN_ERROR = "4";
	
	/** コネクションにアプリケーション情報を追記するかどうか指定 */
	// パラメータ編集必要
	private static final boolean USE_DB_APPLICATION_INFO  = HybsSystem.sysBool( "USE_DB_APPLICATION_INFO" ) ;

	/**
	 * コンストラクター
	 * 初期処理を行います。
	 * 
	 * @og.rev 5.10.16.1 (2019/10/11) fukurou利用に変更
	 * 
	 * @param systemid システムID
	 * @param usrset ユーザID
	 * @param prpupd プログラムID
	 * @param dmnName デーモン名
	 */
	public DBAccessQueue(final String systemid, final String usrset, final String prpupd, final String dmnName) {
		SYSTEM_ID = systemid;
//		USRSET = StringUtils.defaultString(usrset, "UNNONE") ;
//		PGUPD  = StringUtils.defaultString( prpupd, "UNNONE" ) ;
//		DMN_NAME = StringUtils.defaultString( dmnName, "UNNONE" ) ;
		USRSET = StringUtil.nval( usrset, "UNKNOWN" );
		PGUPD  = StringUtil.nval( prpupd, "UNKNOWN" );
		DMN_NAME = StringUtil.nval( dmnName, "UNKNOWN" );

		
		if (USE_DB_APPLICATION_INFO) {
			appInfo = new ApplicationInfo();
			
			// ユーザーID,IPアドレス,ホスト名
			appInfo.setClientInfo(USRSET, HybsSystem.HOST_ADRS, HybsSystem.HOST_NAME);
			// 画面ID,操作,プログラムID
			appInfo.setModuleInfo("DBAccessQueue", null, DMN_NAME);
		}
		else {
			appInfo = null;
		}
	}

	/**
	 * GE65検索
	 * GE65の処理対象リストを取得します。
	 * 
	 * @return 処理対象リスト
	 */
	public String[][] selectGE65() {
		String sql = "SELECT A.YKNO, A.QUEUEID, A.MESSAGE, A.SFDUPID, B.QUESYU, B.JMSURL FROM GE66 A"
				+ " INNER JOIN GE65 B ON A.SYSTEM_ID = B.SYSTEM_ID AND A.QUEUEID = B.QUEUEID AND B.FGJ = '1'"
				+ " WHERE A.SYSTEM_ID = ? AND A.FGKAN = '1' AND A.FGJ = '1'";
		
		String[][] vals = DBUtil.dbExecute(sql, new String[] {SYSTEM_ID}, appInfo, DBID);
		return vals;
	}
	
	/**
	 * エラー状態に更新
	 * 完了フラグをエラー状態に更新して、
	 * エラー情報を格納します。
	 * 
	 * @param ykno 要求番号
	 * @param errMsg エラーメッセージ
	 */
	public void updateGE66Error(String ykno, String errMsg) {
		String updSql = "UPDATE GE66 SET FGKAN = ?, ERRMSG = ?"
				+ "WHERE SYSTEM_ID = ? AND FGJ = '1' AND YKNO = ?";
		DBUtil.dbExecute(updSql, new String[] {
				FGKAN_ERROR, errMsg, SYSTEM_ID, ykno
		}, appInfo, DBID);
	}
	
	/**
	 * 完了フラグの更新
	 * 完了フラグを指定された値に更新します。
	 * 
	 * @param ykno 要求番号
	 * @param fgkan 完了フラグ
	 */
	public void updateGE66(String ykno, String fgkan) {
		final String dyset = HybsSystem.getDate(DYSET_YMD);
		String updSql = "UPDATE GE66 SET FGKAN = ?, DYUPD = ?, USRUPD = ?, PGUPD = ?"
				+ "WHERE SYSTEM_ID = ? AND FGJ = '1' AND YKNO = ?";
		DBUtil.dbExecute(updSql, new String[] {
				fgkan, dyset, USRSET, PGUPD, SYSTEM_ID, ykno}, appInfo, DBID);
	}
	/**
	 * 受信管理データ取得
	 * 受信管理テーブルから、キューIDとbizlogic名を取得します。
	 * 
	 * @return 受信管理リスト
	 */
	public String[][] setlectGE67() {
		// 対象 キュー名(グループ名)とbizlogic名の取得処理
		final String sql = "SELECT QUEUEID, BIZLOGICID FROM GE67"
				+ " WHERE SYSTEM_ID = ? AND FGJ = '1'";
		final String[][] vals = DBUtil.dbExecute(sql, new String[] {SYSTEM_ID}, appInfo, DBID);
		return vals;
	}

	/**
	 * 処理番号生成
	 * GE68_SEQUENCEからシーケンス番号を生成します。
	 * 
	 * @return 処理番号
	 */
	public String generateSyoriNo() {
		String syoriNo = "";
		
		Transaction tran = new TransactionReal( appInfo );
		
		// 処理番号生成
		try {
			DBFunctionName dbName = DBFunctionName.getDBName( ConnectionFactory.getDBName( DBID ) );
			syoriNo = Integer.toString(dbName.getSequence("GE68S01", tran, DBID));
		}finally {
			tran.close();
		}
		
		return syoriNo;
	}
	
	/**
	 * GE68(キュー受信結果テーブル)更新
	 * キュー受信結果テーブルを指定された完了状態に更新します。
	 * 
	 * @param syno 処理番号
	 * @param fgkan 完了フラグ
	 */
	public void updateGE68(final String syno,  final String fgkan) {
		final String dyset = HybsSystem.getDate(DYSET_YMD);
		
		final String sql = "UPDATE GE68 SET FGKAN = ?, DYUPD = ?, USRUPD = ?, PGUPD = ?"
				+ "WHERE FGJ = '1'"
				+ " AND SYSTEM_ID = ?"
				+ " AND SYNO = ?";
		
		String[] data = new String[] {fgkan, dyset, USRSET, PGUPD, SYSTEM_ID, syno};
		
		// sql実行
		DBUtil.dbExecute(sql, data, appInfo, DBID);
	}
	
	/**
	 *  GE68(キュー受信結果テーブル)登録
	 * キュー受信結果テーブルに受信データを登録します。 
	 * 
	 * @param queueNm キュー名
	 * @param syno 処理NO
	 * @param bizlogicId bizLogicId
	 * @param messageText メッセージ
	 */
	public void insertGE68(final String queueNm, final String syno, final String bizlogicId
			,final String messageText) {
		final String dyset = HybsSystem.getDate(DYSET_YMD);
		final String sql = "INSERT INTO GE68(SYSTEM_ID, QUEUEID, SYNO, BIZLOGICID, MESSAGE, FGKAN, FGJ,"
				+ "DYSET, DYUPD, USRSET, USRUPD, PGSET,  PGUPD)" 
				+ " VALUES(?,?,?,?,?,?,'1'"
				+ ",?,?,?,?,?,?)";
		
		final String[] data = new String[] {
				SYSTEM_ID, queueNm, syno, bizlogicId, messageText, DBAccessQueue.FGKAN_PROCESS
				,dyset, dyset, USRSET,  USRSET, PGUPD, PGUPD
		};
		
		// sql実行
		DBUtil.dbExecute(sql,  data, appInfo, DBID);
	}
	
	/**
	 * GE68(キュー受信結果テーブル)エラー更新
	 * キュー受信結果テーブルをエラー状態に更新します。
	 * 
	 * @param syoriNo 処理NO
	 * @param errMsg エラーメッセージ
	 */
	public void updateGE68Error(String syoriNo, final String errMsg) {
		// エラーテーブルに登録
		final String ymd = HybsSystem.getDate(DYSET_YMD);
		final String sql = "UPDATE GE68"
				+ " SET ERRMSG = ?, FGKAN = ?"
				+ " ,DYUPD = ?, USRUPD = ?, PGUPD = ?"
				+ " WHERE SYSTEM_ID = ? AND FGJ = '1' AND SYNO = ? ";

		final String[] data = new String[] { errMsg // エラーメッセージ
				,DBAccessQueue.FGKAN_ERROR
				,ymd
				,USRSET
				,PGUPD
				,SYSTEM_ID
				, syoriNo
		};

		// sql実行
		DBUtil.dbExecute(sql, data, appInfo, DBID);
	}
}
