package com.gh.control;

import java.net.SocketAddress;
import java.nio.channels.SeekableByteChannel;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;

import com.gh.model.AddInfo;
import com.gh.model.DelInfo;
import com.gh.model.LoginInfo;
import com.gh.model.Pepole;
import com.gh.model.SendInfo;
import com.gh.utils.Tools;
import com.gh.view.SeverFrame;

/**
 * ·þÎñÆ÷ÏûÏ¢´¦Àí³ÌÐò
 * 
 * @author NIIT
 *
 */
public class ServerIOHandler extends IoHandlerAdapter {

	// ´æ´¢ËùÓÐµÄ¿Í»§¶Ë
	private List<IoSession> clients = new ArrayList<>();// µ±Ç°Á¬½Ó
	private HashMap<String, String> linksInfo = new HashMap<String, String>();// Á¬½ÓÓëµØÖ·
	private HashMap<String, IoSession> idAndSession = new HashMap<String, IoSession>();// Á¬½ÓÓëµØÖ·
	private ArrayList<Pepole> pepoles = new ArrayList<Pepole>();
	private ArrayList<String> onlinePepoles = new ArrayList<String>();// ÔÚÏßÓÃ»§
	private LoginInfo lgi;
	private SeverFrame severFrame;

	public ServerIOHandler(SeverFrame severFrame) {
		this.severFrame = severFrame;
	}

	/**
	 * ÓÐ¿Í»§¶ËÁ¬½Ó ´¥·¢
	 */
	@Override
	public void sessionCreated(IoSession session) throws Exception {
		// Ìí¼Ó
		clients.add(session);
		System.out.println(session.getRemoteAddress() + "Á¬½Ó·þÎñÆ÷");
		// ·¢Éú»á»°´´½¨µÄ ¿Í»§¶ËµØÖ·
	}

	/**
	 * ¿Í»§¶Ë¹Ø±Õ»á»° ´¥·¢
	 */
	@Override
	public void sessionClosed(IoSession session) throws Exception {
		// ·¢Éú»á»°½áÊøµÄ ¿Í»§¶ËµØÖ·
		SocketAddress address = session.getRemoteAddress();
		System.out.println("¡¾ServerIOHandler»á»°ÍË³ö¡¿" + address);// µ÷ÊÔÊä³ö
		// nowp.setOnline(false);//ÉèÖÃµ±Ç°ÓÃ»§×´Ì¬
		if (linksInfo.get(session.getRemoteAddress().toString()) != null) {// ÅÅ³ý³¢ÊÔÁ¬½ÓºÍ×¢²áÁ¬½ÓÏÂÏßÊ±ÌáÊ¾
			severFrame.addText(linksInfo.get(session.getRemoteAddress()
					.toString()) + "ÏÂÏß");// ¸üÐÂÎÄ±¾ÓòÐÅÏ¢
			severFrame.delUser(linksInfo.get(session.getRemoteAddress()
					.toString()));// ÔÚ·þÎñ¶Ë ÔÚÏßÓÃ»§ÁÐ±íÉÏÉ¾³ý
			severFrame.delnotalk(linksInfo.get(session.getRemoteAddress()
					.toString()));//ÔÚ½ûÑÔÁÐ±íÉ¾Ò»ÏÂ
			// ·¢ËÍ¸ø±ðÈË¸üÐÂÔÚÏßºÃÓÑ
			onlinePepoles.remove(linksInfo.get(session.getRemoteAddress()
					.toString()));
			// linksInfo.remove(session.getRemoteAddress().toString());//ÁªÏµÒÆ³ý
			idAndSession.remove(linksInfo.get(session.getRemoteAddress()
					.toString()));// idÓësessionÁªÏµÒÆ³ý
			sendMessageToAllClient("ÓÃ»§ÏÂÏß~"
					+ linksInfo.get(session.getRemoteAddress().toString()));
		}
		// É¾³ýÁ¬½Ó
		clients.remove(session);

	}

	/**
	 * ÊÕµ½¿Í»§¶ËÏûÏ¢ ´¥·¢
	 */
	@Override
	public void messageReceived(IoSession session, Object message)
			throws Exception	{
		// ¿Í»§¶ËµØÖ·
		SocketAddress address = session.getRemoteAddress();
		System.err.println("·þÎñÆ÷ÊÕµ½ÐÅÏ¢:"+message);
		// Èç¹ûÊÇµÇÂ½ÐÅÏ¢
		if (message instanceof LoginInfo) {
			lgi = (LoginInfo) message;
			// ²éÎÄ¼þ»ñµÃÊý¾Ý¿âÐÅÏ¢
			pepoles = Tools.readFile();
			boolean flag = true;// ÑéÖ¤µÇÂ½±ê¼Ç£¬true±íÊ¾ÃÜÂë´íÎó
			for (Pepole p : pepoles) {
				if (lgi.getId().equals(p.getId())
						&& lgi.getPwd().equals(p.getPassword())) {
					// ÅÐ¶ÏÊÇ²»ÊÇÒÑ¾­µÇÂ½
					boolean isOnline = false;
					for (String onlineId : onlinePepoles) {
						if (p.getId().equals(onlineId)) {
							isOnline = true;
						}
					}
					if (isOnline) {//Èç¹ûÔÚÏß
						session.write("ÄãÒÑ¾­ÔÚÏß");
						flag = false;
						break;
					} else {
						session.write("ÔÊÐíµÇÂ½~" + p.getName() + "~" + p.getId());// ·µ»ØÒ»¸öÍ¨¹ýµÄ±ê¼Ç¼ÓÓÃ»§µÄÐÕÃûÓÃÓÚ¿Í»§¶ËÏÔÊ¾ÓÃ»§ÐÕÃû
						flag = false;// ±ê¼ÇÑéÖ¤Í¨¹ý
						onlinePepoles.add(p.getId());// Ìí¼Óµ½ÔÚÏßÈË
						linksInfo.put(address.toString(), p.getId());// Ìí¼ÓµØÖ·ÓëidÓ³Éä
						idAndSession.put(p.getId(), session);// Ìí¼ÓidÓësessionµÄÓ³Éä
						severFrame.addText(p.getId() + "ÉÏÏß");// ·þÎñÆ÷¶ËÏÔÊ¾ÓÃ»§µÇÂ¼
						severFrame.AddUserToList(p.getId());// ·þÎñÆ÷ÔÚÏßÁÐ±íÏÔÊ¾id
						// ·¢ËÍÏûÏ¢¸øËùÓÐÔÚÏßµÄÓÃ»§
						sendMessageToAllClient("ÓÃ»§ÉÏÏß~" + p.getId());
						break;
					}
				}
			}
			if (flag) {
				session.write("²»ÐíµÇÂ½");// ÃÜÂë´íÎó
			}
			// Èç¹ûÊÇÌí¼ÓºÃÓÑÐÅÏ¢
		} else if (message instanceof AddInfo) {
			AddInfo addInfo = (AddInfo) message;
			// ´ÓÎÄ±¾ÖÐ²éÕÒÊÇ²»ÊÇÓÐÕâ¸öid
			pepoles = Tools.readFile();
			// ÊÇ·ñÒÑ¾­Ìí¼ÓÎªºÃÓÑ
			boolean flag = true;
			for (Pepole p : pepoles) {
				if (p.getId().equals(addInfo.getFriendId())) {
					flag = false;
					if (Tools.writeFile(addInfo)) {
						session.write("Ìí¼ÓºÃÓÑ³É¹¦");
						System.out.println("Ð´Èë³É¹¦");
					} else {
						session.write("Ìí¼ÓºÃÓÑÊ§°Ü");
						System.out.println("Ð´ÈëÊ§°Ü");
					}
				}
			}
			if (flag) {
				session.write("Ìí¼ÓºÃÓÑÊ§°Ü");
				System.out.println("Ð´ÈëÊ§°Ü");
			}
			// Èç¹ûÊÇ×¢²áÐÅÏ¢
		} else if (message instanceof Pepole) {
			Pepole p = (Pepole) message;
			if (Tools.writeFile(p)) {
				session.write("×¢²á³É¹¦");
			} else {
				session.write("×¢²áÊ§°Ü");
			}
			// Èç¹ûÊÇ×Ö·û´®
		} else if (message instanceof String) {
			String s = (String) message;
			if ("²éÕÒºÃÓÑ".equals(s)) {
				System.out.println("·þÎñÆ÷ÊÕµ½²éÑ¯"
						+ linksInfo.get(session.getRemoteAddress().toString())
						+ "µÄºÃÓÑ");
				ArrayList<Pepole> friends = Tools.readUseFriendFile(linksInfo
						.get(session.getRemoteAddress().toString()));
				String friendsName = "ºÃÓÑÁÐ±í~";
				for (Pepole p : friends) {
					friendsName += p.getId() + "~";// ·¢ËÍºÃÓÑµÄid
				}
				friendsName = friendsName
						.substring(0, friendsName.length() - 1);// È¥µô×îºóÒ»¸ö/
				session.write(friendsName);
			} else if ("²éÕÒÔÚÏßºÃÓÑ".equals(s)) {
				String onlineFriends = "ÔÚÏßºÃÓÑ~";
				for (String op : onlinePepoles) {
					onlineFriends += op + "~";
				}
				onlineFriends = onlineFriends.substring(0,
						onlineFriends.length() - 1);
				session.write(onlineFriends);
			}else if(s.startsWith("ºÃÓÑÐÅÏ¢")){
				s=s.substring(5);
				ArrayList<Pepole> use = Tools.readFile();
				for(Pepole p:use){
					if(p.getId().equals(s)){
						session.write(p);
					}
				}
			}
			
			
		} else if (message instanceof DelInfo) {
			DelInfo delInfo = (DelInfo) message;
			if (Tools.writeFile(delInfo)) {
				// true ºÃÓÑÎÄ¼þÀïÓÐÇÒÉ¾³ý³É¹¦
				// false ºÃÓÑÎÄ¼þÃ»ÓÐÄÇid »ò ¸ÃidºÃÓÑÎª¿Õ£¬ÎÄ¼þ²»´æÔÚ
				session.write("É¾³ýºÃÓÑ³É¹¦");
				System.out.println("É¾³ýºÃÓÑ³É¹¦");
			} else {
				session.write("É¾³ýºÃÓÑÊ§°Ü");
				System.out.println("É¾³ýºÃÓÑÊ§°Ü");
			}
		} else if (message instanceof SendInfo) {
			SendInfo sendInfo = (SendInfo) message;
			if (sendInfo.getDescId().equals("ËùÓÐÔÚÏßÓÃ»§")) {// Èç¹ûÄ¿±êidÊÇËùÓÐÈË
				System.err.println("·þÎñÆ÷×ª·¢" + sendInfo + "¸øËùÓÐÈË");
				severFrame.addText("·þÎñÆ÷×ª·¢ÏûÏ¢" + sendInfo + "¸ø"+ sendInfo.getDescId());
				sendMessageToAllClient(sendInfo);
			} else {// ·¢ËÍµ¥¸öºÃÓÑ
					// ¸ú¾ÝÓ³ÉäidÓësessionÓ³ÉäÄÃµ½session
				System.err.println("·þÎñÆ÷×ª·¢ÏûÏ¢" + sendInfo + "¸ø"+ sendInfo.getDescId());
				
				severFrame.addText("·þÎñÆ÷×ª·¢ÏûÏ¢" + sendInfo + "¸ø"+ sendInfo.getDescId());
				if (idAndSession.get(sendInfo.getDescId()) != null)// Èç¹ûÄ¿±êidÔÚÏß
					idAndSession.get(sendInfo.getDescId()).write(sendInfo);
				else {
					// Ä¿±ê²»ÔÚÏß
					session.write("ÓÃ»§²»ÔÚÏß");
				}
			}
		}
	}

	/**
	 * ·¢ËÍÏûÏ¢¸øËùÓÐ¿Í»§¶Ë
	 * 
	 * @param msg
	 */
	public void sendMessageToAllClient(Object msg) {
		for (IoSession session : clients) {
			session.write(msg);
		}
	}
	/**
	 * ¸ù¾ÝidÄÃsession
	 * @param id
	 * @return
	 */
	public IoSession getIdSession(String id) {
		return idAndSession.get(id);
	}
}
