package org.opengion.hayabusa.queue;

// import org.apache.commons.lang3.StringUtils;					// 7.0.6.0 (2019/10/07)
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.db.ApplicationInfo;					// 7.0.6.0 (2019/10/07)	util → db に移動のため
import org.opengion.hayabusa.common.HybsSystem;
import org.opengion.fukurou.system.DateSet;						// 7.0.6.0 (2019/10/07)	HybsSystem.getDate( String )

/**
 * キュー処理用の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 ;
	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;
	private final ApplicationInfo appInfo ;			// 7.2.9.4 (2020/11/20) PMD:Possible unsafe assignment to a non-final static field in a constructor.

	/** 処理中 {@value} */
	public static final String  FGKAN_PROCESS = "2";
	/** 完了 {@value} */
	public static final String  FGKAN_END = "3";
	/** エラー{@value} */
	public static final String  FGKAN_ERROR = "4";

	/** コネクションにアプリケーション情報を追記するかどうか指定 */
	// パラメータ編集必要
	private static final boolean USE_DB_APPLICATION_INFO  = HybsSystem.sysBool( "USE_DB_APPLICATION_INFO" ) ;

	/**
	 * コンストラクター
	 * 初期処理を行います。
	 *
	 * @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") ;			// 7.0.6.0 (2019/10/07)
//		PGUPD  = StringUtils.defaultString( prpupd, "UNNONE" ) ;		// 7.0.6.0 (2019/10/07)
//		DMN_NAME = StringUtils.defaultString( dmnName, "UNNONE" ) ;		// 7.0.6.0 (2019/10/07)
		USRSET		= usrset  == null ? "UNNONE" : usrset ;				// "" の時、"" を返す必要がある。StringUtil.nval は、"" と null を同値に扱う
		PGUPD		= prpupd  == null ? "UNNONE" : prpupd ;
		DMN_NAME	= dmnName == null ? "UNNONE" : dmnName ;

		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() {
		final 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'";

		// 7.2.9.4 (2020/11/20) PMD:Consider simply returning the value vs storing it in local variable 'vals'
		return DBUtil.dbExecute(sql, new String[] {SYSTEM_ID}, appInfo, DBID);
//		final String[][] vals = DBUtil.dbExecute(sql, new String[] {SYSTEM_ID}, appInfo, DBID);
//		return vals;
	}

	/**
	 * エラー状態に更新
	 * 完了フラグをエラー状態に更新して、
	 * エラー情報を格納します。
	 *
	 * @param ykno 要求番号
	 * @param errMsg エラーメッセージ
	 */
	public void updateGE66Error(final String ykno, final String errMsg) {
		final 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(final String ykno, final String fgkan) {
//		final String dyset = HybsSystem.getDate(DYSET_YMD);
		final String dyset = DateSet.getDate(DYSET_YMD);			// 7.0.6.0 (2019/10/07)
		final 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'";

		// 7.2.9.4 (2020/11/20) PMD:Consider simply returning the value vs storing it in local variable 'vals'
		return DBUtil.dbExecute(sql, new String[] {SYSTEM_ID}, appInfo, DBID);
//		final String[][] vals = DBUtil.dbExecute(sql, new String[] {SYSTEM_ID}, appInfo, DBID);
//		return vals;
	}

	/**
	 * 処理番号生成
	 * GE68_SEQUENCEからシーケンス番号を生成します。
	 *
	 * @og.rev 7.0.6.4 (2019/11/29) TransactionRealのclose漏れ対応
	 *
	 * @return 処理番号
	 */
	public String generateSyoriNo() {
		String syoriNo = "";

//		final Transaction tran = new TransactionReal( appInfo );

		// 処理番号生成
		try( Transaction tran = new TransactionReal( appInfo ) ) {				// 7.0.6.4 (2019/11/29) try-with-resources文
//		try {
			final 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 dyset = DateSet.getDate(DYSET_YMD);			// 7.0.6.0 (2019/10/07)

		final String sql = "UPDATE GE68 SET FGKAN = ?, DYUPD = ?, USRUPD = ?, PGUPD = ?"
				+ "WHERE FGJ = '1'"
				+ " AND SYSTEM_ID = ?"
				+ " AND SYNO = ?";

		final 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 ﾋﾞｽﾞﾛｼﾞｯｸID
	 * @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 dyset = DateSet.getDate(DYSET_YMD);			// 7.0.6.0 (2019/10/07)

		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(final String syoriNo, final String errMsg) {
		// エラーテーブルに登録
//		final String dyset = HybsSystem.getDate(DYSET_YMD);
		final String dyset = DateSet.getDate(DYSET_YMD);			// 7.0.6.0 (2019/10/07)

		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
				, dyset
				, USRSET
				, PGUPD
				, SYSTEM_ID
				, syoriNo
		};

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