using IceCoffee.Common.Extensions;
using System.Text;
namespace langguanApi.Model
{
    /// 
    /// 数据段
    /// 
    public class DataSegment
    {
        /// 
        /// 默认应答系统编码
        /// 
        public const string ResponseST = "91";
        /// 
        /// 请求编号
        /// 
        /// 
        /// yyyyMMddHHmmssZZZ 取当前系统时间, 精确到毫秒值, 用来唯一标识一次命令交互
        /// 
        public string QN { get; set; }
        /// 
        /// 系统编号
        /// 
        public string ST { get; set; }
        /// 
        /// 命令编码
        /// 详见附录 2
        /// 
        public CommandNumber CN { get; set; }
        /// 
        /// 访问密码
        /// 对接时提供给各个对接站点
        /// 
        public string PW { get; set; }
        /// 
        /// 设备唯一标识
        /// 对接时提供给各个对接站点
        /// 
        public string MN { get; set; }
        /// 
        /// 拆分包及应答标志
        /// 
        public PackageFlag PackageFlag { get; set; }
        /// 
        /// 总包数
        /// PNUM 指示本次通讯中总共包含的包数,注:不分包时可以没有本字段,与标志位有关
        /// 
        public int PNUM { get; set; }
        /// 
        /// 包号
        /// PNO 指示当前数据包的包号,注: 不分包时可以没有本字段,与标志位有关
        /// 
        public int PNO { get; set; }
        /// 
        /// 指令
        /// CP=&&数据区&&( 详见表 5 )
        /// 
        public CpCommand CpCommand { get; set; }
        /// 
        /// 解析
        /// 
        /// 
        /// 
        /// 
        public static DataSegment Parse(string data, Func unpackCacheFunc)
        {
            DataSegment dataSegment = new DataSegment();
            try
            {
                int outEnd;
                dataSegment.QN = data.GetMidStr("QN=", ";", out outEnd);
                if (outEnd < 0)
                {
                    outEnd = 0;
                }
                dataSegment.ST = data.GetMidStr("ST=", ";", out outEnd, outEnd);
                dataSegment.CN = (CommandNumber)int.Parse(data.GetMidStr("CN=", ";", out outEnd, outEnd));
                dataSegment.PW = data.GetMidStr("PW=", ";", out outEnd, outEnd);
                dataSegment.MN = data.GetMidStr("MN=", ";", out outEnd, outEnd);
                string packageFlag = data.GetMidStr("Flag=", ";", out outEnd, outEnd);
                if (string.IsNullOrEmpty(packageFlag) || int.TryParse(packageFlag, out _) == false || outEnd < 0)
                {
                    outEnd = 0;
                }
                else
                {
                    dataSegment.PackageFlag = PackageFlag.Parse(packageFlag);
                }
                if (dataSegment.PackageFlag != null && dataSegment.PackageFlag.D == 1)
                {
                    // 分包
                    dataSegment.PNUM = int.Parse(data.GetMidStr("PNUM=", ";", out outEnd, outEnd));
                    dataSegment.PNO = int.Parse(data.GetMidStr("PNO=", ";", out outEnd, outEnd));
                    string cp = data.GetMidStr("CP=&&", "&&", out outEnd, outEnd);
                    var cache = unpackCacheFunc.Invoke();
                    if (dataSegment.PNO == 1)// 第一个包
                    {
                        cache.Append(cp);
                    }
                    else if (dataSegment.PNUM == dataSegment.PNO)// 最后一个包
                    {
                        cache.Append(cp.Substring(23));
                        dataSegment.CpCommand = CpCommand.Parse(cache.ToString());
                        cache.Clear();
                    }
                    else// 中间的包
                    {
                        cache.Append(cp.Substring(23));// 23 - DataTime=20170920100000; 留分号
                    }
                }
                else
                {
                    string cp = data.GetMidStr("CP=&&", "&&", out outEnd, outEnd);
                    // 过滤心跳包
                    dataSegment.CpCommand = dataSegment.CN == CommandNumber.HeartbeatPackage ? new CpCommand() : CpCommand.Parse(cp);
                }
                return dataSegment;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error in DataSegment.Parse:{ex.Message}");
            }
            return dataSegment;
        }
        /// 
        /// 序列化
        /// 
        /// 
        public string Serialize()
        {
            return $"QN={QN};ST={ST};CN={(int)CN};PW={PW};MN={MN};Flag={PackageFlag.Serialize()};CP=&&{CpCommand.Serialize()}&&";
        }
    }
}