package org.opengion.plugin.daemon;

import java.util.Date;

import javax.jms.QueueSession;

import org.hsqldb.lib.StringUtil;
import org.opengion.fukurou.db.DBUtil;
import org.opengion.fukurou.queue.QueueInfo;
import org.opengion.fukurou.queue.QueueSend;
import org.opengion.fukurou.queue.QueueSendFactory;
import org.opengion.fukurou.util.ApplicationInfo;
import org.opengion.fukurou.util.HybsTimerTask;
import org.opengion.hayabusa.common.HybsSystem;

/**
 * メッセージキュー送信
 * メッセージキュー送信テーブルを監視して、
 * 送信処理を行います。
 * 
 * @og.group メッセージ連携
 * 
 * @version 5.0
 * @author oota
 * @since JDK7
 *
 */
public class Daemon_QueueSend extends HybsTimerTask {
	private int loopCnt = 0;
	private static final int LOOP_COUNTER = 24;
	private QueueSend queueSend;

	private String SYSTEM_ID = HybsSystem.sys("SYSTEM_ID");
	private static final ApplicationInfo appInfo = null;
	private static final String DBID = HybsSystem.sys( "RESOURCE_DBID" );
	private static final String CLOUD_SQS_ACCESS_KEY = HybsSystem.sys( "CLOUD_SQS_ACCESS_KEY" );
	private static final String CLOUD_SQS_SECRET_KEY = HybsSystem.sys( "CLOUD_SQS_SECRET_KEY" );
	
	/**
	 * 開始処理
	 * タイマータスクのデーモン処理の開始ポイントです。
	 */
	@Override
	protected void startDaemon() {
		if (loopCnt % LOOP_COUNTER == 0) {
			loopCnt = 1;
			System.out.println();
			System.out.println(toString() + " " + new Date() + "");
		} else {
			// メッセージキュー送信管理テーブルから、送信対象のレコードを取得
			String sql = "select a.system_id, 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);
			
			// 取得データ分の繰り返し処理を実行する
			for(int i = 0; i  < vals.length; i++) {
				String[] record = vals[i];
				
				String systemId = record[0];
				String ykno =  record[1];
				String queueId = record[2];
				String message = record[3];
				String dedupliId = record[4];
				String queSyu = record[5];
				String jmsUrl = record[6];
				
				String queueType = queSyu.toUpperCase();
				queueSend = QueueSendFactory.newQueueSend(queueType);
	
				// 接続処理
				queueSend.connect(jmsUrl, CLOUD_SQS_ACCESS_KEY, CLOUD_SQS_SECRET_KEY);
				
				// メッセージ送信管理テーブルから取得したデータを送信実装予定
				QueueInfo queueInfo = new QueueInfo();
				
				// 応答確認種別
				if("MQ".equals(queueType)){
					// MQメッセージサーバ指定時
					queueInfo.setMqTransacted(false);
					queueInfo.setMqAcknowledgeMode(QueueSession.AUTO_ACKNOWLEDGE);
					// キュー名
					queueInfo.setMqQueueName(queueId);
				}else if("SQS".equals(queueType)){
					// SQSメッセージサーバ指定時
					// グループID
					queueInfo.setSqsFifoGroupId(queueId);
					if(!StringUtil.isEmpty(dedupliId)) {
						// 重複排除ID
						// コンテンツに基づく重複排除が有効時は、未設定でも可(メッセージによる重複判定が行われる)
						queueInfo.setSqsFifoDedupliId(dedupliId);
					}
				}
			
				// メッセージ
				queueInfo.setMessage(message);
			
				// 完了フラグを送信中：２に更新
				updateFgkan(systemId, ykno, "2");
				
				// メッセージ送信処理
				try{
					queueSend.sendMessage(queueInfo);
					
					// 完了フラグを完了：３に更新
					updateFgkan(systemId, ykno, "3");
					
				}catch(Exception e) {
					// 完了フラグをエラー：４に更新
					updateError(systemId, ykno, e.getMessage());
				} 
			}
			
			// クローズ処理
			queueSend.close();
			
			loopCnt++;
		}
	}
	
	/**
	 * 完了フラグの更新
	 * 完了フラグを指定された値に更新します。
	 * 
	 * @param systemId システムID
	 * @param ykno 要求番号
	 * @param fgkan 完了フラグ
	 */
	private void updateFgkan(String systemId, String ykno, String fgkan) {
		String updSql = "update ge66 set fgkan = ?"
				+ "where system_id = ? and fgj = '1' and ykno = ?";
		DBUtil.dbExecute(updSql, new String[] {
				fgkan,systemId, ykno}, appInfo, DBID);
	}
	
	/**
	 * エラー状態に更新
	 * 完了フラグをエラー状態に更新して、
	 * エラー情報を格納します。
	 * 
	 * @param systemId システムID
	 * @param ykno 要求番号
	 * @param errMsg エラーメッセージ
	 */
	private void updateError(String systemId, String ykno, String errMsg) {
		String updSql = "update ge66 set fgkan = '4', errmsg = ?"
				+ "where system_id = ? and fgj = '1' and ykno = ?";
		DBUtil.dbExecute(updSql, new String[] {
				errMsg, systemId, ykno
		}, appInfo, DBID);
	}
}
