using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.IO;
using System.Linq;
using System.Text;
using CacheManager.Core;
using Common;
using Dao;
using RCUHost.Protocols;
using CommonEntity;

namespace RCUHost.Implement
{
    /// <summary>
    /// 心跳包 Receiver
    /// </summary>
    public class HeartReceiver : GenericReceiverBase, IHeartReceiver
    {
        private static log4net.ILog logger = log4net.LogManager.GetLogger(typeof(HeartReceiver));
        public void SendHeart(string hostNumber, string mac)
        {
            byte[] data = CreateDataPacket();
            Send(data, hostNumber, mac);
        }

        public override void Process(ReceiverContext context)
        {
            bool bkb = GenericReceiverBase.DealWwith(context);
            if (bkb == false)
            {
                return;
            }
            //心跳包维持连接
            //新的 使用MAC
            //logger.Error("下位机来连接了");
            //AA 55 17 00 54 33 53 41 02 78 90 1F 08 75 D9 
            //34 D0 B8 11 75 D9  MAC地址
            //D5 B6 
            if (context.Data.Length > 17)
            {
                //logger.Error("下位机来连接了");
                //17: 34-D0-B8-11-5C-77 172.16.5.58:3341
                //logger.Error("17: " + BitConverter.ToString(context.Data, 15, 6)+context.RemoteEndPoint.Address.ToString() + ":" + context.RemoteEndPoint.Port.ToString());
                string Key = BitConverter.ToString(context.Data, 15, 6);

                CSRedisCacheHelper.Set(Key, context.RemoteEndPoint.Address.ToString() + ":" + context.RemoteEndPoint.Port.ToString());//mac地址


                string EndPoint = context.RemoteEndPoint.ToString();

                string hostnum = context.SystemHeader.Value.HostNumber.ToString();
                long hotelcode = context.SystemHeader.Value.HostNumber.ToHotelCode();
                //PO~P5:RCU 主机MAC地址←
                //P6:解析版本←
                //P6:取电状态<
                //P7:设备类型<
                //P8:设备地址<
                //P8~P9:设备回路<
                //P10:设备数据长度<
                //P11~P12:通道电压，单位:10mV
                //P13~P16:通道电流，单位:10mV
                //P17~P20:通道功率，单位:mW
                //P21~P24:通道能耗，单位:Wh(1度电=1KWh)
                //P25~P28:通道总能耗，单位:Wh(1度电=1KWh)
                var Data = context.Data;
                if (Data.Length > 17 + 6)
                {
                    //AA 55 2F 00 54 33 53 41 02 34 80 EB 03 6B 24 
                    //34 D0 B8 11 6B 24 
                    //01 解析版本
                    //01 取电
                    //01 设备数量
                    //39 
                    //01 
                    //01 
                    //00 
                    //10 ///长度
                    //F0 55  //电压 
                    //E8 03  //电流 
                    //E8 03 00 00  功率 
                    //E8 03 00 00 能耗 
                    //E8 03 00 00 总能耗 
                    //9E 00 


                    //byte[] MAC = Data.Skip(15).Take(6).ToArray();

                    //string MACStr = Tools.ByteToString(MAC).Trim();
                    //MACStr = MACStr.Replace(" ", "-");
                    //byte Version = Data.Skip(21).Take(1).FirstOrDefault();

                    ////从第21个数据开始
                    //byte TakeCard = Data.Skip(22).Take(1).FirstOrDefault();

                    ////设备数量
                    //byte DeviceCount = Data.Skip(23).Take(1).FirstOrDefault();
                    //byte LeiXing = Data.Skip(24).Take(1).FirstOrDefault();
                    //byte Address = Data.Skip(25).Take(1).FirstOrDefault();
                    //byte[] Num = Data.Skip(26).Take(2).ToArray();

                    //List<byte> lll = new List<byte>();
                    //lll.Add(LeiXing);
                    //lll.Add(Address);
                    //lll.AddRange(Num);

                    //string address = new DeviceAddress(lll.ToArray()).ToString();

                    //byte Len = Data.Skip(28).Take(1).FirstOrDefault();
                    //byte[] DianYa = Data.Skip(29).Take(2).ToArray();
                    //byte[] DianLiu = Data.Skip(31).Take(2).ToArray();
                    //byte[] Power = Data.Skip(33).Take(4).ToArray();
                    //byte[] PowerUsed = Data.Skip(37).Take(4).ToArray();
                    //byte[] TotalPowerUsed = Data.Skip(41).Take(4).ToArray();
                    //uint dianya = BitConverter.ToUInt16(DianYa, 0);
                    //uint dianliu = BitConverter.ToUInt16(DianLiu, 0);
                    //uint gonglv = BitConverter.ToUInt32(Power, 0);

                    //uint nenghao = BitConverter.ToUInt32(PowerUsed, 0);
                    //uint zongnenghao = BitConverter.ToUInt32(TotalPowerUsed, 0);

                    //double V = (double)dianya * 10 / 1000;
                    //double A = (double)dianliu * 10 / 1000;
                    //double P = (double)gonglv / 1000;

                    //double KW_H = (double)nenghao / 1000;
                    //double Sum_KW_H = (double)zongnenghao / 1000;

                    //NengHao n = new NengHao();
                    //n.HotelCode = hotelcode;
                    //n.HostNumber = hostnum;
                    //n.Mac = MACStr;
                    //n.EndPoint = EndPoint;
                    //n.Version = ((int)Version).ToString();
                    //if (TakeCard == 0x01)
                    //{
                    //    n.IsTakeCard = true;
                    //}
                    //else
                    //{
                    //    n.IsTakeCard = false;
                    //}
                    //n.V = Math.Round(V, 2);
                    //n.A = Math.Round(A, 2);
                    //n.P = Math.Round(P, 2);
                    //n.KW_H = KW_H;
                    //n.Sum_KW_H = Sum_KW_H;

                    //long ti = Tools.GetUnixTime();
                    //n.CreateTime = ti;

                    //string KKey = CacheKey.NengHao + "_" + MACStr;
                    ////CSRedisCacheHelper.Forever<NengHao>(KKey, n);
                    //CSRedisCacheHelper.Set_PartitionWithTime<NengHao>(KKey, n, 30, 1);

                    //string mns = Newtonsoft.Json.JsonConvert.SerializeObject(n);
                    //CSRedisCacheHelper.Publish("redis-power", mns);

                    //string KeyFilter = "能耗";
                    //RCUHost.RCUHostCommon.tools.LanJieData(KeyFilter, hotelcode.ToString());
                }
            }
            else
            {
                //旧版本数据
                //使用hostnumber
                //logger.Error("MAC: "+context.SystemHeader.Value.HostNumber.ToString()+" "+ context.RemoteEndPoint.Address.ToString() + ":" + context.RemoteEndPoint.Port.ToString());
                string Key = context.SystemHeader.Value.HostNumber.ToString();
                string hotelCode = context.SystemHeader.Value.HostNumber.ToHotelCode().ToString();


                //string EEE = CSRedisCacheHelper.Get<string>(Key);
                //if (string.IsNullOrEmpty(EEE))
                //{
                //    OnOffLineData o = new OnOffLineData();
                //    o.HostNumber = Key;
                //    o.HotelCode = hotelCode;
                //    o.CurrentStatus = "on";
                //    o.CurrentTime = DateTime.Now;
                //    //新来的数据
                //    var n = Newtonsoft.Json.JsonConvert.SerializeObject(o);
                //    CSRedisCacheHelper.Publish("redis-on_off_line", n);
                //}



                CSRedisCacheHelper.Set(Key, context.RemoteEndPoint.Address.ToString() + ":" + context.RemoteEndPoint.Port.ToString());//主机编码
                //CSRedisCacheHelper.HMSet(CacheKey.RCUOnLine,Key);

            }
            //判断是否需要给下位机回复命令（下位机判断累计三次未回复则重启主机）
            //string frameNo = Tools.ByteToString(context.Data).Substring(27, 5);//(frameNo == "FF FF")
            if (context.SystemHeader.Value.FrameNo == 65535)
            {
                Send(CreateDataPacket(), context.RemoteEndPoint);
            }
        }

        public override CommandType CommandType
        {
            get { return CommandType.Heart; }
        }

        private byte[] CreateDataPacket()
        {
            using (MemoryStream stream = new MemoryStream())
            {
                var headerLen = StructConverter.SizeOf(typeof(SystemHeader));
                stream.Seek(headerLen, SeekOrigin.Begin);
                stream.Write(new byte[] { 0, 0 }, 0, 2);
                var header = CreateSystemHeader((int)stream.Length - headerLen);
                byte[] headerData = StructConverter.StructToBytes(header);
                stream.Seek(0, SeekOrigin.Begin);
                stream.Write(headerData, 0, headerData.Length);
                return stream.ToArray();
            }
        }
    }
}
