using CommonAI.Zone;
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 TriggerData total = new TriggerData();
			public HashMap<string, TriggerData> profileData = new HashMap<string, TriggerData>();

			public JSGTriggerProfile(int areaId)
			{
				this.areaId = areaId;
			}
		}

		protected static readonly Logger log = LoggerFactory.GetDefLogger();
		private static readonly int STRIGGER_INTERVAL = 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()
		{
			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 void RecordTrigger(int areaId, string triggerName, int timeUse, bool isTrigger)
		{
			JSGTriggerProfile trigger = mZoneTriggers.Get(areaId);
			if (trigger == null)
			{
				trigger = new JSGTriggerProfile(areaId);
				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++;
			}
		}

		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));
			}

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

			log.Info("----------------------场景事件耗时输出----------------------");
			foreach (JSGTriggerProfile info in mZoneTriggers.Values)
			{
				log.Info("##场景触发器总揽:" + info.areaId + ", 检测次数:" + info.total.checkTimes + ", 触发次数: " + info.total.triggerTimes + ", 耗时:" + info.total.timeUse);
				if (info.total.checkTimes < 1000 || info.total.timeUse < 1000)
				{
					continue;
				}

				foreach (KeyValuePair<string, TriggerData> kv in info.profileData)
				{
					log.Info("------场景触发器总揽:" + kv.Key + ", 检测次数:" + kv.Value.checkTimes + ", 触发次数: " + kv.Value.triggerTimes + ", 耗时:" + kv.Value.timeUse);
				}
			}

			log.Info(" ---------------------------------------------------- ");
			return true;
		}
	}
}