package com.zx.sms.handler.api.gate;

import java.util.List;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.commons.lang3.RandomUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.zx.sms.BaseMessage;
import com.zx.sms.common.util.ChannelUtil;
import com.zx.sms.connect.manager.EventLoopGroupFactory;
import com.zx.sms.connect.manager.ExitUnlimitCirclePolicy;
import com.zx.sms.handler.api.AbstractBusinessHandler;
import com.zx.sms.session.cmpp.SessionState;

import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import io.netty.util.concurrent.Promise;

/**
 * 
 * @author Lihuanghe(18852780@qq.com)
 *
 */
public abstract class SessionConnectedHandler extends AbstractBusinessHandler {
	private static final Logger logger = LoggerFactory.getLogger(SessionConnectedHandler.class);

	protected AtomicInteger totleCnt = new AtomicInteger(10);

	public AtomicInteger getTotleCnt() {
		return totleCnt;
	}

	public void setTotleCnt(AtomicInteger totleCnt) {
		this.totleCnt = totleCnt;
	}

	public SessionConnectedHandler() {
	}

	public SessionConnectedHandler(AtomicInteger t) {
		totleCnt = t;
	}

	protected abstract BaseMessage createTestReq(String content);

	@Override
	public void userEventTriggered(final ChannelHandlerContext ctx, Object evt) throws Exception {
		final AtomicInteger tmptotal = totleCnt;
		if (evt == SessionState.Connect) {

			final Channel ch = ctx.channel();
			EventLoopGroupFactory.INS.submitUnlimitCircleTask(new Callable<Boolean>() {

				@Override
				public Boolean call() throws Exception {
					int cnt = RandomUtils.nextInt() & 0x4ff;
					while (cnt > 0 && tmptotal.get() > 0) {
						List<Promise<BaseMessage>> futures = null;
						ChannelFuture chfuture = null;
						BaseMessage msg = createTestReq(UUID.randomUUID().toString());
//						chfuture = ChannelUtil.asyncWriteToEntity(getEndpointEntity().getId(), msg);
						futures = ChannelUtil.syncWriteLongMsgToEntity(getEndpointEntity().getId(), msg);
						
//						chfuture = ctx.writeAndFlush(msg);
						
						if (chfuture != null)
							chfuture.sync();

						if (futures != null) {
							try {
								for (Promise<BaseMessage> future : futures) {
									future.addListener(new GenericFutureListener<Future<BaseMessage>>() {
										@Override
										public void operationComplete(Future<BaseMessage> future) throws Exception {
											if (future.isSuccess()) {
//												 logger.info("response:{}",future.get());
											} else {
//												 logger.error("response:{}",future.cause());
											}
										}
									});
									try {
										future.sync();
									}catch(Exception ex) {}
								}

							} catch (Exception e) {
								e.printStackTrace();
								cnt--;
								tmptotal.decrementAndGet();
								break;
							}
						}
					
						cnt--;
						tmptotal.decrementAndGet();
					}
					return true;
				}
			}, new ExitUnlimitCirclePolicy<Boolean>() {
				@Override
				public boolean notOver(Future<Boolean> future) {
					if (future.cause() != null)
						future.cause().printStackTrace();

					boolean over = ch.isActive() && tmptotal.get() > 0;
					if (!over) {
						logger.info("========send over.============");

						// ch.writeAndFlush(new CmppTerminateRequestMessage());
					}
					return over;
				}
			}, 1);

		}

		ctx.fireUserEventTriggered(evt);
	}

	@Override
	public String name() {
		return "SessionConnectedHandler-Gate";
	}

	public SessionConnectedHandler clone() throws CloneNotSupportedException {
		SessionConnectedHandler ret = (SessionConnectedHandler) super.clone();
		return ret;
	}

}

@@ -343,16 +343,67 @@
 elUtil;%0A
+import com.zx.sms.connect.manager.EndpointManager;%0A
 import c
@@ -1657,24 +1657,193 @@
 .Connect) %7B%0A
+%09%09%09%0A%09%09%09//2.1.12%E7%89%88%E6%9C%AC%E5%90%8E%EF%BC%8C%E5%81%9A%E4%B8%BAServerChildEndpointEntity%E4%B8%8D%E5%86%8D%E8%87%AA%E5%8A%A8%E5%8A%A0%E5%88%B0EndpointManager%E9%87%8C%E4%BA%86%EF%BC%8C%E5%9B%A0%E6%AD%A4%0A%09%09%09//%E8%A6%81%E6%89%8B%E5%8A%A8%E5%8A%A0%E5%85%A5EndpointManager%E8%BF%9B%E8%A1%8C%E7%AE%A1%E7%90%86%0A%09%09%09EndpointManager.INS.addEndpointEntity(getEndpointEntity());%0A%09%09%09
 %0A%09%09%09final Ch

test case