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

import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
// import org.opengion.hayabusa.common.HybsSystemException;

// import com.sun.star.uno.RuntimeException;

/**
 * MQサーバへのメッセージキュー送信用クラス
 * 
 * MQサーバへのメッセージキュー送信用のクラスです。
 * Apache ActiveMQとAmazonMQへの送信が可能です。
 * tomcatからの送信(JNDI利用)と、
 * バッチ処理(urlを指定し接続)の２通りが可能です。
 * 
 * ※Apache ActiveMQとAmazonMQの切り替えは、
 * jmsServerの接続先URLを変更するのみで接続の変更が可能です。
 * (proxy環境からAmazonMqへの接続は行えない場合があります)
 * 
 * @og.group メッセージ連携
 * 
 * @og.rev 5.10.14.0 (2019/08/01) 新規作成
 * 
 * @version 5
 * @author oota
 * @since JDK7
 *
 */
public class QueueSend_MQ implements QueueSend {
	private	Connection		connection;
	private	Session			session;
	private	MessageProducer	sender;
	private	Context			ctx;
	// バッチ用フィールド
	private	boolean batch;
	private	String	mqUserId	= "";
	private	String	mqPassword	= "";

	/**
	 * 接続処理
	 * MQサーバに接続を行います。
	 * 
	 * @param jmsServer jmsサーバ接続名(バッチの場合はurl)
	 */
	public void connect(final String jmsServer) {
		try {
			ctx = new InitialContext();
			// 1. Connectionの作成s
//			QueueConnectionFactory factory = null;
			final QueueConnectionFactory factory;
			if (batch) {
				// バッチ処理の場合。URL指定で、ユーザIDとパスワードを指定して接続。
				mqUserId	= System.getProperty("mqUserId");
				mqPassword	= System.getProperty("mqPassword");
				factory		= new ActiveMQConnectionFactory(jmsServer);
				connection	= (ActiveMQConnection)factory.createConnection(mqUserId, mqPassword);
			} else {
				// tomcat接続の場合。JNDIを利用して接続。
				factory = (QueueConnectionFactory) ctx.lookup("java:comp/env/" + jmsServer);
				connection = (ActiveMQConnection)factory.createConnection();
			}

			// 2. Connectioの開始
			connection.start();

		} catch (final JMSException jmse) {
			throwErrMsg("MQサーバーの接続に失敗しました。" + jmse.getMessage());
		} catch (final NamingException ne) {
			throwErrMsg("名前解決に失敗しました。" + ne.getMessage());
		}
	}

	/**
	 * 接続処理
	 * MQサーバに接続します。
	 * connect(String jmsServer)と同じ処理になります。
	 *
	 * @og.rev 5.10.15.0 (2019/08/30) 引数追加対応
	 * 
	 * @param jmsServer jmsサーバ情報
	 * @param sqsAccessKey アクセスキー(MQサーバでは未使用)
	 * @param sqsSecretKey シークレットキー(MQサーバでは未使用)
	 */
	@Override
	public void connect(final String jmsServer, final String sqsAccessKey, final String sqsSecretKey) {
		// MQではsqsAccessKeyとsqsSecretKeyは利用しません。
		connect(jmsServer);
	}

	/**
	 * エラーメッセージ送信。
	 * 
	 * @og.rev 5.10.15.0 (2019/08/30) Hybs除外
	 * 
	 * @param errMsg エラーメッセージ
	 */
	public void throwErrMsg(final String errMsg) {
		throw new RuntimeException( errMsg );
//		if (batch) {
//			// バッチ用エラー
//			throw new RuntimeException(errMsg);
//		} else {
//			// 画面用エラー
//			throw new HybsSystemException(errMsg);
//		}
	}

	/**
	 * メッセージ送信
	 * MQサーバにメッセージを送信します。
	 * 
	 * @param queueInfo 送信キュー情報
	 */
	@Override
	public void sendMessage(final QueueInfo queueInfo) {
		try {
			// 初期チェック
			if (connection == null) {
				throwErrMsg("MQサーバに接続されていません。");
			}

			// 1. QueueSessionの作成
			session = connection.createSession(queueInfo.isMqTransacted(), queueInfo.getMqAcknowledgeMode());
			if (session == null) {
				throwErrMsg("キューセッションの生成に失敗しました。");
			}

			// 2. Queueの作成
//			Queue queue = null;
//			queue = session.createQueue(queueInfo.getMqQueueName());
			final Queue queue = session.createQueue(queueInfo.getMqQueueName());
			sender = session.createProducer(queue);

			// 3. テキストメッセージの作成
			final TextMessage msg = session.createTextMessage(queueInfo.getMessage());

			// 4. 送信処理
			sender.send(msg);

		} catch (JMSException e) {
			throwErrMsg("キューの送信処理に失敗しました。" + e.getMessage());
		}
	}

	/**
	 * クローズ処理
	 * MQサーバとの接続をクローズします。
	 */
	@Override
	public void close() {
		if (ctx != null) {
			try {
				ctx.close();
			} catch (Exception e) {
				System.out.println("ctxのクローズに失敗しました。");
			}
		}
		// 1. sender,session,connectionのクローズ処理
		if (sender != null) {
			try {
				sender.close();
			} catch (Exception e) {
				System.out.println("senderのクローズに失敗しました。");
			}
		}
		if (session != null) {
			try {
				session.close();
			} catch (Exception e) {
				System.out.println("sessionのクローズに失敗しました。");
			}
		}
		if (connection != null) {
			try {
				connection.close();
			} catch (Exception e) {
				System.out.println("connectionのクローズに失敗しました。");
			}
		}
	}

	/**
	 * バッチ処理判定フラグを設定します。
	 * バッチ処理の場合は引数で接続先情報を与えます。
	 * それ以外の場合(Tomcat)ではJNDIより情報を取得します。
	 * 
	 * @param batchFlg バッチ処理判定フラグ
	 */
	@Override
	public void setBatchFlg(final Boolean batchFlg) {
		batch = batchFlg;
	}

	/**
	 * テスト用メソッド
	 * テスト実行用です。
	 * 
	 * @param args 引数
	 */
	public static void main(final String[] args) {
		System.out.println("main start");
		// 送信情報の設定
		final String url = "tcp://localhost:61616";
		final String queueName = "test01";
		final String msg = "送信メッセージ";
		
		final QueueInfo queueInfo = new QueueInfo();
		queueInfo.setMqQueueName(queueName);
		queueInfo.setMqTransacted(false);
		queueInfo.setMqAcknowledgeMode(QueueSession.AUTO_ACKNOWLEDGE);
		queueInfo.setMessage(msg);

		final QueueSend queueSend = new QueueSend_MQ();
		queueSend.setBatchFlg(true);

		try {
			queueSend.connect(url,null,null);
//			queueSend.connect(url);
			queueSend.sendMessage(queueInfo);
		} catch (final Exception e) {
			System.out.println(e.getMessage());
		} finally {
			queueSend.close();
		}

		System.out.println("main end");
	}
}
