package org.opengion.fukurou.queue;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.jms.MessageListener;

import com.amazonaws.ClientConfiguration;
import com.amazonaws.Protocol;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.auth.InstanceProfileCredentialsProvider;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
import com.amazonaws.services.sqs.model.DeleteMessageRequest;
import com.amazonaws.services.sqs.model.Message;
import com.amazonaws.services.sqs.model.ReceiveMessageRequest;
import com.amazonaws.util.StringUtils;

/**
 * SQSのメッセージ受信用クラス。
 * 
 * SQSサーバからメッセージキューを受信用のクラスです。
 * 
 * @og.group メッセージ連携
 *
 * @og.rev 5.10.15.2 (2019/09/20) 新規作成
 * 
 * @version 5
 * @author oota
 * @since JDK7
 */
public class QueueReceive_SQS implements QueueReceive{
	private AmazonSQS client = null;
	private ReceiveMessageRequest request = null;
	private String sqsServer = "";
	private final static String GROUPID_ATTR = "MessageGroupId";
	
	/**
	 * 接続処理
	 * メッセージキューサーバに接続します。
	 * 
	 *  @param jmsServer jsmサーバ
	 *  @param sqsAccessKey sqs用awsアクセスキー
	 *  @param sqsSecretKey sqs用awsシークレットキー
	 */
	public void connect(final String jmsServer, final String sqsAccessKey, final String sqsSecretKey) {
		// jmsServerをsqsServerとして保持
		sqsServer = jmsServer;
		
		if (StringUtils.isNullOrEmpty(sqsAccessKey)) {
			// IAMロールによる認証
			client = AmazonSQSClientBuilder.standard()
					.withCredentials(new InstanceProfileCredentialsProvider(false)).build();
		} else {
			// アクセスキーによる
			AWSCredentials credentials = new BasicAWSCredentials(sqsAccessKey, sqsSecretKey);
			
	// proxy環境での検証用
//			ClientConfiguration conf = new ClientConfiguration();
//			conf.setProtocol(Protocol.HTTPS);
//			conf.setProxyHost("mtc-px15");
//			conf.setProxyPort(8081);
			
			client = AmazonSQSClientBuilder.standard()
					.withCredentials(new AWSStaticCredentialsProvider(credentials))
//					.withClientConfiguration(conf)
					.withRegion(Regions.AP_NORTHEAST_1.getName())
					.build();
		}
		
		// グループIDを取得できるように、属性を設定
		request = new ReceiveMessageRequest(jmsServer);
		
		List<String> attributeNames = new ArrayList<String>();
		attributeNames.add(GROUPID_ATTR);
		request.setAttributeNames(attributeNames);
	}
	
	/**
	 * 再受信処理
	 * 再受信処理を行います。
	 * 
	 * @param queueName キュー名
	 */
	public QueueInfo receive(final String queueName) {
		QueueInfo queueInfo = null;
		
		// 受信処理
		List<Message> messages = client.receiveMessage(request).getMessages();
		if(messages.size() > 0) {
			final Message message = messages.get(0);
			
			Map<String, String> attriMap = message.getAttributes();
			final String groupId = attriMap.get(GROUPID_ATTR);
			
			queueInfo = new QueueInfo();
			queueInfo.setMessage(message.getBody());
			queueInfo.setSqsFifoGroupId(groupId);
			
			// キューの削除
			client.deleteMessage(new DeleteMessageRequest(sqsServer, message.getReceiptHandle()));
		}
		
		return queueInfo;
	}
	
	/**
	 * 終了処理
	 * APIによる通信処理のため、
	 * SQSでは終了処理は不要です。
	 * 
	 */
	public void close() {
		// 処理なし
	}
	

	/**
	 * SQSではリスナー処理は出来ません。
	 * 
	 * @param queueName キュー名
	 * @param listener MessageListerを実装したクラス
	 */
	@Override
	public void setListener(final String queueName, MessageListener listener) {
		throw new RuntimeException("SQSではsetListenerは利用できません。");
	}

	/**
	 * SQSではリスナー処理は出来ません。
	 */
	@Override
	public void closeListener() {
		throw new RuntimeException("SQSではcloseListenerは利用できません。");
	}
	
	/**
	 * 検証用メソッド
	 * 検証用のmainメソッドです。
	 * 
	 * 下記の値を設定してください。
	 * jmsServer: SQSのURL
	 * sqsAccessKey: SQSの権限を持ったAWSユーザのアクセスキー
	 * sqsSecretKey: 上記と同様のシークレットキー。
	 * 
	 * @param args 引数
	 */
	public static void main(String[] args) {
		QueueReceive_SQS queueReceive_SQS = new QueueReceive_SQS();
		final String jmsServer = System.getProperty("jmsServer");
		final String sqsAccessKey = System.getProperty("sqsAccessKey");
		final String sqsSecretKey = System.getProperty("sqsSecretKey");
		queueReceive_SQS.connect(jmsServer, sqsAccessKey, sqsSecretKey);
		
		// 受信処理
		// SQSはgropuIdの指定は出来ません．
		final QueueInfo queueInfo = queueReceive_SQS.receive(null);
		
		if(queueInfo != null) {
			System.out.println("groupId:" + queueInfo.getSqsFifoGroupId());
			System.out.println("message:" + queueInfo.getMessage());
		}else {
			System.out.println("キューが存在しません");
		}
	}
	
	/**
	 * バッチ処理判定フラグを設定します。
	 * 
	 * @param batchFlg バッチ処理判定フラグ
	 */
	public void setBatchFlg(final Boolean batchFlg) {
		// SQSはバッチでも同じ処理になります。
	}
}
