using System;

namespace ET.Client
{
    [Invoke(TimerInvokeType.SessionIdleChecker)]
    public class SessionIdleChecker: ATimer<SessionIdleCheckerComponent>
    {
        protected override void Run(SessionIdleCheckerComponent self)
        {
            try
            {
                self.Check();
            }
            catch (Exception e)
            {
                Log.Error($"idle check error: {self.Id}\n{e}");
            }
        }
    }
    
    [ObjectSystem]
    public class SessionIdleCheckerComponentAwakeSystem: AwakeSystem<SessionIdleCheckerComponent>
    {
        protected override void Awake(SessionIdleCheckerComponent self, params object[] param)
        {
            self.RepeatedTimer = TimerComponent.Instance.NewRepeatedTimer(ConstValue.SessionTimeoutTime / 2 +100, TimerInvokeType.SessionIdleChecker, self);
        }
    }

    [ObjectSystem]
    public class SessionIdleCheckerComponentDestroySystem: DestroySystem<SessionIdleCheckerComponent>
    {
        protected override void Destroy(SessionIdleCheckerComponent self)
        {
            TimerComponent.Instance?.Remove(ref self.RepeatedTimer);
        }
    }

    public static class SessionIdleCheckerComponentSystem
    {
        public static void Check(this SessionIdleCheckerComponent self)
        {
            Session session = self.GetParent<Session>();
            long timeNow = TimeHelper.ClientNow();

            if (timeNow - session.LastRecvTime < ConstValue.SessionTimeoutTime/2 && timeNow - session.LastSendTime < ConstValue.SessionTimeoutTime/2)
            {
                return;
            }

            session.Send(new C2G_Ping());
        }
    }
}