using CommonAI.Data;
using CommonAI.Zone;
using CommonAI.Zone.Instance;
using CommonLang;
using CommonLang.Log;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//using System.Threading.Tasks;

namespace CommonAI.ZoneServer.JSGModule
{
	public class JSGServerProfile
	{
		public class JSGProfileData
		{
			public long times = 0;
			public long size = 0;
		}

		public class ZoneCreateInfo
		{
			public int areaId;
			public int mTotalTimes;
			public int mTotalTimeUse;
		}

		public class TriggerData
		{
			public long checkTimes = 0;     // 检测次数
			public long triggerTimes = 0;   // 触发次数			
			public long timeUse = 0;        // 触发耗时
		}

		public class JSGTriggerProfile
		{
			// 总触发次数<100 || 总耗时小于<3000 将会被过滤输出
			public int areaId;
			public long areaCreateTime;
			public TriggerData total = new TriggerData();
			public HashMap<string, TriggerData> profileData = new HashMap<string, TriggerData>();

			public JSGTriggerProfile(int areaId, long createTime)
			{
				this.areaId = areaId;
				this.areaCreateTime = createTime;
			}
		}

		protected static readonly Logger log = LoggerFactory.GetDefLogger();
		private static int STRIGGER_INTERVAL = 2 * 3600 * 1000;

		//////////////////////////////////////////////////////////////////////////////////
		//数据统计		
		private static HashMap<int, JSGProfileData> mSendProfile = new HashMap<int, JSGProfileData>();
		private static HashMap<int, JSGProfileData> mRecProfile = new HashMap<int, JSGProfileData>();

		//记录创建场景信息
		private static HashMap<int, ZoneCreateInfo> mZoneCreate = new HashMap<int, ZoneCreateInfo>();
		//场景触发器触发次数,耗时统计(场景id: 时间名,统计数据)
		private static HashMap<int, JSGTriggerProfile> mZoneTriggers = new HashMap<int, JSGTriggerProfile>();

		private static long mNextPrintTime;
		//////////////////////////////////////////////////////////////////////////////////

		public static void init()
		{
			if (GlobalData.GAME_BS_TEST)
            {
				STRIGGER_INTERVAL = 300 * 1000;
			}

			mNextPrintTime = CommonLang.CUtils.CurrentTimeMS + STRIGGER_INTERVAL;
		}

		public static void RecordSend(int typeID, long msgSize)
		{
			JSGProfileData profile = mSendProfile.Get(typeID);
			if (profile == null)
			{
				profile = new JSGProfileData();
				mSendProfile.Put(typeID, profile);
			}
			profile.times++;
			profile.size += msgSize;
		}

		public static void RecordRecv(int typeID, long msgSize)
		{
			//log.Warn("收到消息:" + typeID);
			JSGProfileData profile = mRecProfile.Get(typeID);
			if (profile == null)
			{
				profile = new JSGProfileData();
				mRecProfile.Put(typeID, profile);
			}
			profile.times++;
			profile.size += msgSize;
		}

		/** 记录场景创建耗时 */
		public static void RecordZoneCreate(int areaId, int timeUse)
		{
			ZoneCreateInfo zoneInfo = mZoneCreate.Get(areaId);
			if (zoneInfo == null)
			{
				zoneInfo = new ZoneCreateInfo();
				zoneInfo.areaId = areaId;
				mZoneCreate.Put(areaId, zoneInfo);
			}

			zoneInfo.mTotalTimes++;
			zoneInfo.mTotalTimeUse += timeUse;
		}

		/** 记录场景触发器耗时 */
		public static bool RecordTrigger(InstanceZone zone, string triggerName, int timeUse, bool isTrigger)
		{
			int areaId = zone.GetSceneID();
			JSGTriggerProfile trigger = mZoneTriggers.Get(areaId);
			if (trigger == null)
			{
				trigger = new JSGTriggerProfile(areaId, zone.mCreateTime);
				mZoneTriggers.Put(areaId, trigger);
			}

			trigger.total.timeUse += timeUse;
			trigger.total.checkTimes++;

			TriggerData triggerData = trigger.profileData.Get(triggerName);
			if (triggerData == null)
			{
				triggerData = new TriggerData();
				trigger.profileData.Put(triggerName, triggerData);
			}

			triggerData.checkTimes++;
			triggerData.timeUse += timeUse;

			if (isTrigger)
			{
				trigger.total.triggerTimes++;
				triggerData.triggerTimes++;
			}

			zone.mTotalTimeUse += timeUse;
			zone.mTotalTrigers++;
			return zone.mTotalTimeUse > 1000 || zone.mTotalTrigers > 50000;
		}

		public static bool CheckPrintAllData()
		{
			if(mNextPrintTime > CommonLang.CUtils.localTimeMS)
			{
				return false;
			}

			mNextPrintTime = CommonLang.CUtils.CurrentTimeMS + STRIGGER_INTERVAL;
			log.Info(" --------------------- PackEvent send ------------------- ");
			foreach (KeyValuePair<int, JSGProfileData> kv in mSendProfile)
			{
				log.Info(" - - - - - MsgID = " + kv.Key + ",\t Size = " + kv.Value.size +
					", \ttimes = " + kv.Value.times + ", \t avg = " + (kv.Value.size / kv.Value.times));
			}

			log.Info(" --------------------- PackEvent recv ------------------- ");
			foreach (KeyValuePair<int, JSGProfileData> kv in mRecProfile)
			{
				log.Info(" - - - - - MsgID = " + kv.Key + ",\t Size = " + kv.Value.size + ", \ttimes = " + kv.Value.times + ", \t avg = " + (kv.Value.size / kv.Value.times));
			}

			JSGPrintLog("----------------------创建场景耗时统计输出----------------------");
			foreach (ZoneCreateInfo info in mZoneCreate.Values)
			{
				JSGPrintLog("##创建场景耗时统计:" + info.areaId + ", " + info.mTotalTimes + ", " + info.mTotalTimeUse);
			}

			JSGPrintLog("----------------------场景事件耗时输出----------------------");
			long curTime = CommonLang.TimeUtil.GetTimestampMS();
			foreach (JSGTriggerProfile info in mZoneTriggers.Values)
			{
				JSGPrintLog("##触发器总揽: " + info.areaId + ", 运行: " + (curTime - info.areaCreateTime) + ", 创建时间: " + info.areaCreateTime +
					", 检测数: " + info.total.checkTimes + ", 触发数: " + info.total.triggerTimes + ", 耗时: " + info.total.timeUse);
				if (info.total.checkTimes > 300000 || info.total.timeUse > 1000 || info.total.triggerTimes > 50000)
				{
					foreach (KeyValuePair<string, TriggerData> kv in info.profileData)
					{
						JSGPrintLog("------触发器详细:" + kv.Key + ", 检测次数:" + kv.Value.checkTimes + ", 触发次数: " + kv.Value.triggerTimes + ", 耗时:" + kv.Value.timeUse);
					}
				}			
			}

			JSGPrintLog(" ---------------------------------------------------- ");
			return true;
		}

		private static void JSGPrintLog(string data)
        {
			if (GlobalData.GAME_BS_TEST)
            {
				log.Warn(data);
            }
            else
            {
				log.Info(data);
            }

		}
	}
}