using MessagePack;
using Newtonsoft.Json;
using ServiceCenter;
using ServiceCenter.Redis;
using WCS.Core;
using WCS.Entity.Protocol.DataStructure;

namespace WCS.Service
{
    public class ProtocolProxy : ProtocolProxyBase
    {
        public static DeviceDataPack DataPack { get; set; } = new DeviceDataPack();

        public ProtocolProxy(Device dev, ProtocolInfo info, Type protocolType, World world) : base(dev, info, protocolType, world)
        {
            #region 初始化Redis连接

            var redisConnectionStrings = RedisHub.Default.Check("RedisConnectionStrings") ?? throw new Exception("请在Redis中配置RedisConnectionStrings");
            var configs = JsonConvert.DeserializeObject<List<DataBaseConnectionString>>(redisConnectionStrings);
            if (configs != null)
            {
                if (configs.All(v => v.Key != "Monitor")) throw new Exception("请在RedisConnectionStrings中配置监控RedisDB库连接字符串");
            }

            foreach (var redisConnection in configs!)
            {
                RedisHub.CreateContext(redisConnection.ConnectionString, redisConnection.Key);
                switch (redisConnection.Key)
                {
                    case "Monitor":
                        RedisHub.SetMonitorContextType(redisConnection.Key);
                        RedisHub.Monitor.Serialize = obj =>
                        {
                            var bytes = MessagePackSerializer.Serialize(obj);
                            return bytes;
                        };
                        RedisHub.Monitor.DeserializeRaw = (bytes, type) =>
                        {
                            var obj = MessagePackSerializer.Deserialize(type, bytes);
                            return obj;
                        };
                        break;

                    case "DebugRedisUrl":
                        RedisHub.SetDebugContextType(redisConnection.Key);
                        Configs.DebugRedisUrl = redisConnection.ConnectionString;
                        break;

                    case "WMS":
                        RedisHub.SetWMSContextType(redisConnection.Key);
                        break;
                }
            }

            #endregion 初始化Redis连接
        }

        protected override void DataChanged()
        {
            //if (Device.HasProtocol(typeof(IStation520)))
            //{
            //    if (DataPack.StationDatas == null)
            //    {
            //        DataPack.StationDatas = new DeviceDataCollection<StationData>();
            //    }
            //    DataPack.StationDatas.Datas.Append(new StationData()
            //    {
            //        Code = Device.Code,
            //        D520 = Copy(this, typeof(IStation520).Assembly.GetTypes().Where(v => v.IsClass).Where(v => v.GetInterface(typeof(IStation520).Name) != null && v != this.GetType()).First()) as WCS_Station520,
            //        D521 = Copy(this, typeof(IStation521).Assembly.GetTypes().Where(v => v.IsClass).Where(v => v.GetInterface(typeof(IStation521).Name) != null && v != this.GetType()).First()) as WCS_Station521,
            //        D523 = Copy(this, typeof(IStation523).Assembly.GetTypes().Where(v => v.IsClass).Where(v => v.GetInterface(typeof(IStation523).Name) != null && v != this.GetType()).First()) as WCS_Station523,
            //    }); ;
            //    DataPack.StationDatas.Frame = DateTime.Now;
            //}
            //else if (Device.HasProtocol(typeof(ISRM520)))
            //{
            //    if (DataPack.SRMDatas == null)
            //    {
            //        DataPack.SRMDatas = new DeviceDataCollection<SRMData>();
            //    }
            //    DataPack.SRMDatas.Datas.Append(new SRMData()
            //    {
            //        Code = Device.Code,
            //        D520 = Copy(this, typeof(ISRM520).Assembly.GetTypes().Where(v => v.IsClass).Where(v => v.GetInterface(typeof(ISRM520).Name) != null && v != this.GetType()).First()) as WCS_SRM520,
            //        D521 = Copy(this, typeof(ISRM521).Assembly.GetTypes().Where(v => v.IsClass).Where(v => v.GetInterface(typeof(ISRM521).Name) != null && v != this.GetType()).First()) as WCS_SRM521,
            //        D537 = Copy(this, typeof(ISRM537).Assembly.GetTypes().Where(v => v.IsClass).Where(v => v.GetInterface(typeof(ISRM537).Name) != null && v != this.GetType()).First()) as WCS_SRM537,
            //    });
            //    DataPack.SRMDatas.Frame = DateTime.Now;
            //}
            //else if (Device.HasProtocol(typeof(IBCR81)))
            //{
            //    if (DataPack.BcrDatas == null)
            //    {
            //        DataPack.BcrDatas = new DeviceDataCollection<BCRData>();
            //    }
            //    DataPack.BcrDatas.Datas.Append(new BCRData()
            //    {
            //        Code = Device.Code,
            //        Bcr81 = Copy(this, typeof(IBCR81).Assembly.GetTypes().Where(v => v.IsClass).Where(v => v.GetInterface(typeof(IBCR81).Name) != null && v != this.GetType()).First()) as WCS_BCR81,
            //    });
            //    DataPack.BcrDatas.Frame = DateTime.Now;
            //}
            //DataPack.Frame = DateTime.Now;
        }

        private object Copy(object obj, Type type)
        {
            var res = Activator.CreateInstance(type);
            foreach (var p in type.GetProperties())
            {
                var p2 = obj.GetType().GetProperty(p.Name);
                if (p2 != null && p2.PropertyType == p.PropertyType)
                {
                    p.SetValue(res, p2.GetValue(obj));
                }
            }
            return res;
        }
    }
}
