using System;
using System.Diagnostics;
using JLHHJSvr.BLL;
using JLHHJSvr.Com;
using JLHHJSvr.Helper;
using LJLib.Net.SPI.Com;
using Newtonsoft.Json;

namespace LJLib.Net.SPI.Server
{
    internal abstract class ExcutorBase
    {
        public abstract LJResponse Excute(ILJRequest request, object state);
    }

    internal abstract class ExcutorBase<T1, T2> : ExcutorBase
        where T1:ILJRequest<T2>
        where T2:LJResponse,new()
    {
        protected abstract void ExcuteInternal(T1 request, object state, T2 rslt);

        protected virtual bool PreHandle(T1 request, T2 rslt) {
            if(request is ILJTokenRequest<T2> request2)
            {
                var tokendata = BllHelper.GetToken(request2.token);
                if (tokendata == null)
                {
                    rslt.ErrMsg = "会话已经中断，请重新登录";
                    return false;
                }
                Trace.Write($"用户名: {tokendata.username}, 请求类型: {typeof(T1).Name},请求报文:\r\n{JsonConvert.SerializeObject(request2)}", "Request");

                if (request is ILJLockRequest<T2> request3)
                {
                    if (LockHelper.PreCheckBillLock(request3, out string arg_msg))
                    {
                        rslt.ErrMsg = arg_msg;
                        return false;
                    }
                }
            }
            return true; 
        }

        public override LJResponse Excute(ILJRequest request, object state)
        {
            T2 rslt = new T2();
            try
            {
                T1 req = request as T1;
                if (req == null)
                {
                    rslt.ErrMsg = "request不能转换成类型" + typeof(T1).Name;
                    return rslt;
                }
                if (PreHandle(req, rslt))
                {
                    ExcuteInternal(req, state, rslt);
                }
            }
            catch (Exception ex)
            {
                Trace.Write(ex.ToString());
                rslt.ErrMsg = ex.ToString();
            }
            return rslt;
        }
    }
}
