/*
 * Copyright 2012 The Netty Project
 *
 * The Netty Project licenses this file to you 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:
 *
 *   https://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 kr.gmtc.tss.netty;

import java.util.Queue;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;

import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

/**
 * Handler implementation for the object echo client. It initiates the ping-pong
 * traffic between the object echo client and server by sending the first
 * message to the server.
 */
@Sharable
public class StringClientHandler 
//extends SimpleChannelInboundHandler<Object>{
extends ChannelInboundHandlerAdapter {

	private static Logger logger = LoggerFactory.getLogger(StringClientHandler.class);

	String threadNm="";

	Queue<String> dataQueue;

	StringClient client;
	
	long reconnTime=3000;
	
	long queueFullCnt=0;
	
	ApplicationContext appContext;

	public StringClientHandler(StringClient client, String threadNm, Queue<String> dataQueue, long reconnTime) {
		this.threadNm=threadNm;
		this.dataQueue=dataQueue;
		this.client=client;
		this.reconnTime=reconnTime;
	}

	@Override
	public void channelActive(ChannelHandlerContext ctx) {
		logger.info("서버 접속 - " + ctx.channel().remoteAddress().toString());
	}
	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) {

//			logger.info(msg.toString());
			if(dataQueue!=null) {
				if(!dataQueue.offer(msg.toString())) {
					logger.debug("Client data queue is full!");
				}
			}else {
				logger.error("dataQueue is null!");
			}
			
	}

	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		logger.info("서버 연결 해제 - " +ctx.channel().remoteAddress());
		
		ctx.close();
		super.channelInactive(ctx);
	 
	}
	
	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) {
		ctx.flush();
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
		
		logger.info("접속 오류 발생- " + ctx.channel().remoteAddress().toString()+"/cause : "+cause.getLocalizedMessage());
		
		logger.debug("",cause);
		
		ctx.close();
	}
	
	@Override
	public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
		// TODO Auto-generated method stub
//		super.channelUnregistered(ctx);

		logger.info("접속 불가 - " + client.HOST+":"+client.PORT+" - "+client.reconnTime+"초 후 재 접속 시도 합니다.");
		ctx.channel().eventLoop().schedule(new Runnable() {
			
			@Override
			public void run() {
				logger.info("재접속 시도 - "+ client.HOST+":"+client.PORT);
				client.connecServer();
			}
		}, client.reconnTime, TimeUnit.SECONDS);
		super.channelUnregistered(ctx);
	}
	
	/*private void reConnection(ChannelHandlerContext ctx) {
		String serverAddr=ctx.channel().remoteAddress()+"";
		logger.info("서버 재연결 시작 - "+serverAddr);
		ctx.flush();
		ctx.close();
        Thread reconThread = new Thread(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				while(!ctx.channel().isRegistered ()) {
					logger.info("서버 재연결 시도 - "+ctx.channel().remoteAddress());
//					client.getEventLoop().shutdownGracefully();
//
//					if(!client.getEventLoop().isShutdown()){
//						logger.info("No Shutdown before");
//						threadSleep(reconnTime);
//						continue;
//					}
					
					if(client.startClient()) {
						break;
					}
					
						threadSleep(reconnTime);
				}
				
			}
		});
 
        reconThread.start();
	}*/
	
	private void threadSleep(long millis) {
		try {
			Thread.sleep(millis);
		} catch (InterruptedException e) {
			logger.debug("thread sleep fail",e);
		}
	}

//	@Override
//	protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
//		// TODO Auto-generated method stub
//
//		logger.info(msg.toString());
//		if(dataQueue!=null) {
//			if(!dataQueue.offer(msg.toString())) {
//				logger.error("Client data queue is full!");
//			}
//		}else {
//			logger.error("dataQueue is null!");
//		}
//	}
}
