package com.rndchina.aisin.chat.handler;

import java.io.Serializable;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.rndchina.aisin.util.Util;

public class MinaServerHandler extends IoHandlerAdapter {
	private final static Logger LOGGER = LoggerFactory
			.getLogger(MinaServerHandler.class);

	Logger log = LoggerFactory.getLogger(MinaServerHandler.class);

	// 当前所有用户的session
	// private final Set<IoSession> sessionsSet = Collections
	// .synchronizedSet(new HashSet<IoSession>());
	// 当前所有用户
	// private final Set<String> usersSet = Collections
	// .synchronizedSet(new HashSet<String>());

	Gson gson = new Gson();

	private final Map<String, IoSession> usersMap = Collections
			.synchronizedMap(new HashMap<String, IoSession>());

	@Override
	public void exceptionCaught(IoSession session, Throwable cause) {
		LOGGER.warn("Unexpected exception.", cause);
		cause.printStackTrace();
		// Close connection when unexpected exception is caught.
		// session.close(true);
	}

	@Override
	public void messageReceived(IoSession session, Object message) {
		try {
			String json = message.toString();
			System.out.println("server : <<<< " + json);

			int positon = json.indexOf("}");
			json = json.substring(0, positon + 1);
			System.out.println(json);

			MyMessage msg = gson.fromJson(json, MyMessage.class);

			String username = msg.getUsername();
			String model = msg.getModel();
			String mymsg = msg.getMessage();
			String date = msg.getDate();
			msg.setDate(Util.DatetoString(new Date()));

			String key = "";// username+model
			if (null != username && null != model) {
				key = username + model;
			}

			if ("login".equals(model)) {
				if (!usersMap.containsKey(key)) {
					session.setAttribute("key", key);
					usersMap.put(key, session);
				} else {
					IoSession hasLoginSession = usersMap.get(key);
					hasLoginSession.close(true);
					session.write("用户已登录，请更换用户登录或强制再次登录！");
					return;
				}

				session.write("ok");

				// msg.setUsername("system");
				// msg.setModel("chat");
				// msg.setMessage("[" + username + "] 加入群聊");
				//
				// String chatJson = gson.toJson(msg);
				// broadcast(chatJson);

			} else if ("chat".equals(model)) {
				if (!usersMap.containsKey(key)) {
					session.setAttribute("key", key);
					usersMap.put(key, session);
				}

				String chatJson = gson.toJson(msg);
				broadcast(chatJson);
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}

	}

	public void broadcast(String message) {
		synchronized (usersMap) {
			Set<String> keys = usersMap.keySet();
			int i = 0;
			for (String key : keys) {
				if (key.contains("chat")) {
					IoSession session = usersMap.get(key);
					if (session.isConnected()) {
						session.write(message);
						System.out.println(++i + "****[" + key + "]****"
								+ message);
					} else {
						System.out.println("****" + key + "**** is close");
					}

				}
			}

		}
	}

	@Override
	public void sessionClosed(IoSession session) throws Exception {
		String key = (String) session.getAttribute("key");
		System.out.println("sessionClosed : <<<< " + session.toString() + "<<<"
				+ key);
		// usersSet.remove(user);
		// sessionsSet.remove(session);

		usersMap.remove(key);

		if (null != key && key.contains("chat")) {
			MyMessage msg = new MyMessage();
			msg.setUsername("system");
			msg.setModel("chat");
			msg.setDate(Util.DatetoString(new Date()));

			msg.setMessage(key.replace("chat", "") + " [#system#]已经滚犊子了");
			String chatJson = gson.toJson(msg);
			broadcast(chatJson);
		}

	}

	// public boolean isChatUser(String name) {
	// return usersSet.contains(name);
	// }
	//
	// public int getNumberOfUsers() {
	// return usersSet.size();
	// }

}

class MyMessage implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String username;
	private String model;

	private String message;
	private String date;

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getMessage() {
		return message;
	}

	public String getModel() {
		return model;
	}

	public void setModel(String model) {
		this.model = model;
	}

	public void setMessage(String message) {
		this.message = message;
	}

	public String getDate() {
		return date;
	}

	public void setDate(String date) {
		this.date = date;
	}

}
