package com.mgr.group;

import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;

import com.mgr.group.data.Group;
import com.taurus.core.events.Event;
import com.taurus.core.events.IEventListener;
import com.taurus.core.plugin.redis.Redis;
import com.taurus.core.routes.Extension;
import com.taurus.core.routes.Routes;
import com.taurus.core.util.Logger;
import com.taurus.permanent.TPServer;
import com.taurus.permanent.core.TPEvents;
import com.taurus.permanent.data.Session;
import com.taurus.web.TWebServer;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.exceptions.JedisConnectionException;

/**
 * 
 * 
 */
public class MainServer extends Extension implements IEventListener {

	public static MainServer	instance;

	private GroupSubscriber		subscriber;
	public Config				config;

	@Override
	public void onStart() {
		try {
			instance = this;

			Global.logger = Logger.getLogger(MainServer.class);
			Global.init();

			try {
				loadConfig();
			} catch (Exception e1) {
				Global.logger.error(e1);
			}

			final String svr_key = "svr_mgr_" + config.mgrId;
			Global.loggerDebug = config.loggerDebug;
			TPServer.me().getEventManager().addEventListener(TPEvents.EVENT_SESSION_DISCONNECT, this);

			TPServer.me().getTimerPool().scheduleAtFixedRate(new Runnable() {

				@Override
				public void run() {
					try {
						int size = Global.sessionMgr.size();
						final Map<String, String> svr_info = new HashMap<>();
						svr_info.put("host", config.host);
						svr_info.put("conns", size + "");
						Jedis jedis11 = Redis.use("group1_db11").getJedis();
						try {
							jedis11.hmset(svr_key, svr_info);
							jedis11.expire(svr_key, 15);
							jedis11.zadd(GroupSubscriber.CHANNEL_NAME, size, svr_key);
						}finally {
							jedis11.close();
						}
					} catch (Exception e) {
						Global.logger.error(e);
					}
				}
			}, 0, 5, TimeUnit.SECONDS);

			TPServer.me().getTimerPool().scheduleAtFixedRate(new Runnable() {

				@Override
				public void run() {
					List<Group> list = new ArrayList<Group>(Global.groupMap.values());
					for (Group group : list) {
						if ((System.currentTimeMillis() - group.lastTime) >= 360000000) {
							group.enqueueRunnable(new Runnable() {

								@Override
								public void run() {
									group.destroy();
								}
							});
						}
					}
				}
			}, 10, 10, TimeUnit.SECONDS);

			subscriber = new GroupSubscriber();
			Thread subscribeThread = new Thread(new Runnable() {

				@Override
				public void run() {
					try {
						Redis.use("group1_db11").subscribe(subscriber, GroupSubscriber.CHANNEL_NAME);
					} catch (JedisConnectionException e) {
						Redis.use("group1_db11").subscribe(subscriber, GroupSubscriber.CHANNEL_NAME);
					}
				}
			});
			subscribeThread.start();

			Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {

				@Override
				public void run() {
					Redis.use("group1_db11").unsubscribe(subscriber);
					Redis.use("group1_db11").zrem(GroupSubscriber.CHANNEL_NAME, svr_key);
				}
			}));
		}catch (Exception e){
			Global.logger.error(e);
		}
	}

	protected void loadConfig() throws Exception {
		FileInputStream is = new FileInputStream(TWebServer.me().getContextRealPath()+"/config/mgr-config.xml");
		SAXBuilder builder = new SAXBuilder();
		Document document = builder.build(is);
		Element root = document.getRootElement();
		Config config = new Config();
		config.host = root.getChildTextTrim("host");
		config.mgrId = Integer.parseInt(root.getChildTextTrim("mgrId"));
		config.loggerDebug = Boolean.parseBoolean(root.getChildTextTrim("loggerDebug"));
		this.config = config;
	}

	public void onStop() {
		super.onStop();
	}

	@Override
	public void handleEvent(Event evt) {
		String evtName = evt.getName();
		switch (evtName) {
		case TPEvents.EVENT_SESSION_DISCONNECT:
			Session session = (Session) evt.getParameter(TPEvents.PARAM_SESSION);
			Global.sessionMgr.disconnect(session);
			break;
		}
	}

	@Override
	public void configRoute(Routes me) {
		Global.groupCtr = new GroupController();
		me.add("", Global.groupCtr);
	}
	

}
