package com.mjlogin.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.data.bean.GameBean;
import com.data.cache.AccountCache;
import com.data.cache.GameCache;
import com.data.util.ErrorCode;
import com.data.util.EventType;
import com.data.util.Utility;
import com.mjlogin.Protocol;
import com.mjlogin.WebInterceptor;
import com.taurus.core.entity.ITArray;
import com.taurus.core.entity.ITObject;
import com.taurus.core.entity.TArray;
import com.taurus.core.entity.TObject;
import com.taurus.core.plugin.redis.Redis;
import com.taurus.core.plugin.redis.RedisLock;
import com.taurus.core.routes.ActionKey;
import com.taurus.core.util.Logger;
import com.taurus.core.util.StringUtil;
import com.taurus.web.Controller;
import com.taurus.web.WebException;

import redis.clients.jedis.Jedis;

public class RoomService  extends Controller{

	private static Logger		log		= Logger.getLogger(RoomService.class);


	/**
	 * 创建房间
	 * 
	 * @param router
	 * @throws Exception
	 */
	@ActionKey(value=Protocol.CREATE_ROOM,validate=WebInterceptor.V_SESSION)
	public final  void createRoom() throws Exception {
		String session = this.getSession();
		ITObject reqData = this.getParams();
		Jedis jedis0 = Redis.use("group1_db0").getJedis();
		RedisLock lock = null;
		try {

			lock = new RedisLock(session, jedis0);
			lock.lock();
			String oldRoom = jedis0.hget(session, "room");
			boolean selected = StringUtil.isNotEmpty(oldRoom);
			if (selected) {
				throw new WebException(ErrorCode.BE_IN_ROOM);
			}
			int gameId = reqData.getInt("game_id");
			GameBean gb = GameCache.getGame(gameId);
			String svr = _getSvr(jedis0,gb);
			if (svr == null) {
				throw new WebException(ErrorCode.NO_SERVICE);
			}

			ITObject configData = reqData.getTObject("config_data");
			int maxPlayers = gb.maxPlayers;
			if(configData.containsKey("maxPlayers")) {
				maxPlayers = configData.getInt("maxPlayers");
			}
	
			int opt = configData.getInt("opt");
			Integer pay = gb.pay.get("pay"+opt+"_"+maxPlayers);
			if(pay == null) {
				log.warn("pay no set!");
				throw new WebException(ErrorCode._FAILED);
			}
			int uid = AccountCache.getAccount(session).id;
			if(pay>0) {
				ArrayList<Long> result_list = Utility.payDiamo(jedis0, session,pay);
				if(result_list==null) {
					throw new WebException(ErrorCode._FAILED);
				}
				long result = result_list.get(0);
				if(result !=0) {
					throw new WebException(ErrorCode.NO_DIAMO);
				}
				long cur_diamo = result_list.get(1);
				Utility.payDiamo(EventType.REDIS_EVENT_CREATE_ROOM, uid, gameId, pay,(int)cur_diamo, 0,0);
			}

			List<String> server_ip = jedis0.hmget(svr, "ip", "port");
			String newRoomId = Redis.use("group1_db1").rpop("free_room");
			Redis.use("group1_db1").lpush("free_room", newRoomId);
			String createCode = "room:" + newRoomId;
			Long timeMillis = System.currentTimeMillis()/1000;
			
			
			Map<String, String> roomMap = new HashMap<String, String>();
			roomMap.put("id", newRoomId);
			roomMap.put("owner", session);
			roomMap.put("svr", svr);
			roomMap.put("create_time", timeMillis+"");

			roomMap.put("AA", "0");
			roomMap.put("pay", pay + "");
			roomMap.put("agent", "0");
			roomMap.put("payer", uid+"");
			roomMap.put("maxPlayers", maxPlayers + "");
			roomMap.put("times",gb.opt.get(opt)+"");
			roomMap.put("opt", opt + "");
			roomMap.put("status", "0");
			configData.del("opt");
			configData.del("AA");
			configData.del("maxPlayers");
			roomMap.put("options", configData.toJson());
			roomMap.put("game", gameId + "");
			roomMap.put("open", "1");
			roomMap.put("round", "0");
			roomMap.put("score_"+uid, "0");
			roomMap.put("players", "["+uid+"]");
			roomMap.put("seats", "[1]");
			jedis0.hmset(createCode, roomMap);
			
//			if (pay != 0) {
//				Utility.payDiamo(EventType.REDIS_EVENT_CREATE_ROOM, uid, gameId, pay, 0);
//			}
			jedis0.hset(session, "room", createCode);
			if(Utility.API_VER == 1) {
				jedis0.hset(session, "seat", "1");
			}
			
			ITObject resData = TObject.newInstance();
			resData.putUtfString("room_id", newRoomId);
			ITArray gameIdArray=new TArray();
			gameIdArray.addInt(gameId);
			ITObject gameObj = gb.getTObject();
			resData.putTObject("game_info",gameObj);
			resData.putUtfString("server_ip", server_ip.get(0));
			resData.putUtfString("server_port", server_ip.get(1));
			sendResponse(ErrorCode._SUCC, resData);
		} finally {
			if (lock != null)
				lock.unlock(false);
			jedis0.close();
		}
	}

	public static final ITObject publicJoinRoom(String session, String room_key,String platform)throws Exception {
		Jedis jedis0 = Redis.use("group1_db0").getJedis();
		RedisLock lock = null;
		try {
			String finalRoom = room_key;
			int uid = AccountCache.getAccount(session).id;
			lock = new RedisLock(session, jedis0);
			lock.lock();
			
			String oldRoom = Utility.getOldRoomV2(jedis0,0,session,uid);
            boolean enter_old = false;
            if(StringUtil.isNotEmpty(oldRoom)) {
    			enter_old = true;
    			finalRoom = oldRoom;
            }

			
			List<String> room_list = jedis0.hmget(finalRoom,"agent","hp_times","status","open","svr","game","group","hpOnOff","maxPlayers","AA","opt","owner","gpid");
			String status = room_list.get(2);
			if(StringUtil.isEmpty(status)) {
				throw new WebException(ErrorCode.NO_ROOM_NUM);
			}
			int _status = Integer.parseInt(status);
			if (_status == 3 || _status == 2) {
				if(Utility.API_VER == 1) {
					jedis0.hdel(session, "room","seat");
				}else {
					jedis0.hdel(session, "room");
				}
				throw new WebException(ErrorCode.GROUP_ROOM_DEL);
			}

			int hp_times = 10;
			String agent = room_list.get(0);
			
			if(StringUtil.isNotEmpty(agent)) {
				int _agent = Integer.parseInt(agent);
				if(!enter_old&&_agent==1) {
					throw new WebException(ErrorCode.ROOM_IS_GROUP);
				}
				String hp_times_str = room_list.get(1);
				hp_times = StringUtil.isNotEmpty(hp_times_str)?Integer.parseInt(hp_times_str):10;
				hp_times = _agent==1?hp_times:10;
			}
			
			int gameId = Integer.parseInt(room_list.get(5));
			GameBean gb = GameCache.getGame(gameId);
			if(!enter_old) {
				String open = room_list.get(3);
				if (StringUtil.isEmpty(open) || open.equals("0")) {
					throw new WebException(ErrorCode.ROOM_CLOSE);
				}
			}

			
			String svr = room_list.get(4);
			if (svr == null || !jedis0.exists(svr)) {
				svr = _getSvr(jedis0,gb);
			}
			if (svr == null) {
				throw new WebException(ErrorCode.NO_SERVICE);
			}
			jedis0.hset(finalRoom, "svr", svr);
			jedis0.hset(session, "room", finalRoom);

			ITObject resData = TObject.newInstance();
			resData.putUtfString("room_id", finalRoom.replace("room:", ""));
			resData.putInt("hp_times", hp_times);
			ITObject gameObj = gb.getTObject();
			resData.putTObject("game_info",gameObj);
			resData.putInt("status", _status);
			List<String> server_ip = jedis0.hmget(svr, "ip", "port");
			resData.putUtfString("server_ip", server_ip.get(0));
			resData.putUtfString("server_port", server_ip.get(1));
			String g_str = room_list.get(6);
			int groupId = 0;
			if(StringUtil.isNotEmpty(g_str)) {
				groupId = Integer.parseInt(g_str);
				
			}
			String hpOnOff_str = room_list.get(7);
			int hpOnOff = 0;
			if(StringUtil.isNotEmpty(hpOnOff_str)) {
				hpOnOff = Integer.parseInt(hpOnOff_str);
			}
			resData.putInt("hpOnOff", hpOnOff);
			if(groupId>0) {
				resData.putInt("groupId", groupId);
				String gpid = room_list.get(12);
				resData.putInt("pid", StringUtil.isNotEmpty(gpid)?Integer.parseInt(gpid):0);
				String gm_key = "gm_"+groupId+"_"+uid;
				String lev_str = Redis.use("group1_db10").hget(gm_key, "lev");
				int lev = 3;
				if(StringUtil.isNotEmpty(lev_str)) {
					lev = Integer.parseInt(lev_str);
				}
				resData.putInt("lev", lev);
			}
			
			return resData;
		} finally {
			if (lock != null)
				lock.unlock(false);
			jedis0.close();
		}
	}
	
	
	
	/**
	 * 创建房间
	 * 
	 * @param router
	 * @throws Exception
	 */
	@ActionKey(value=Protocol.JOIN_ROOM,validate=WebInterceptor.V_SESSION)
	public  final  void joinRoom() throws Exception {
		String session = this.getSession();
		ITObject reqData = this.getParams();
		try{
			String room_key = "room:"+reqData.getUtfString("room_id");
			String platform = reqData.getUtfString("platform");
			sendResponse(ErrorCode._SUCC,publicJoinRoom(session, room_key,platform));
		}catch (WebException e) {
			sendResponse(e.getCode(),null);
		}catch (Exception e) {
			e.printStackTrace();
			sendResponse(500,null);
		}
		
	}

	private static final String _getSvr(Jedis jedis0,GameBean gb){
		String svr=null;
		Set<String> gamesvrs = gb.svr_list;
		Integer conns = null;
		for(String str : gamesvrs) {
			String currConns = jedis0.hget(str, "conns");
			if (conns == null && currConns != null || (conns != null && currConns != null && Integer.parseInt(currConns) < conns)) {
				conns = Integer.parseInt(currConns);
				svr = str;
			}
		}
		return svr;
	}

	
	
}
