using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DotNettyFrom.common;
using DotNettyFrom.config;
using DotNettyFrom.db;
using DotNettyFrom.model;
using DotNettyFrom.util;
using NUnit.Framework;

namespace DotNettyFrom.generatecmd
{
    /// <summary>
    /// 不用缓存了,直接直接Select(查询)数据库
    /// </summary>
    public class Water2CmdGenetor : CmdGenetor
    {
        public override string GetLoginCmd(string ccid)
        {
            string cmd = DeviceId + "0214" + ccid;
            return "7e7e7e" + CmdUtil.CalcCrc16Code(cmd);
        }

        public override string GetHeartbeat()
        {
            string cmd = DeviceId + "03020001";
            return "7e7e7e" + CmdUtil.CalcCrc16Code(cmd).ToUpper();
        }

        public override string GetReplyCmd(string receiveCmd)
        {
            //功能码
            int cmdId = GetCmdId(receiveCmd);
            Console.WriteLine("功能码=" + cmdId + "; 16=" + Utils.tenToHex(cmdId));


            if (SystemConfig.HeartbeatDownCmdCode == cmdId)
            {
                if (SystemConfig.IsLogHeartBeatInfo)
                {
                    DataModel.ReceCollection.Add(new UIInfoModel("收到心跳", receiveCmd));
                }
                return null;
            }

            //处理主动上报的回复&心跳.那些不用回复

            //处理主动上报的回复&心跳.那些不用回复

            DataModel.ReceCollection.Add(new UIInfoModel("收到", receiveCmd));


            if (cmdId == int.MinValue)
            {
                DataModel.ReceCollection.Add(new UIInfoModel("帧错误", receiveCmd)
                    .setAction(-1)
                    .setSendType(SystemConfig.ReplyType));
                return null;
            }


            WvBean wb = DbHelper.GetInstance().SelectOneCmdByIndex(cmdId);

            if (wb == null)
            {
                DataModel.ReceCollection.Add(
                    new UIInfoModel("本地数据库没有这样的功能码=(" + cmdId + ") ;16进制=(" +
                                    Utils.tenToHex(cmdId) + ")", receiveCmd)
                        .setAction(-1)
                        .setSendType(SystemConfig.ReplyType));
                return null;
            }

            int pos = 2 * (SystemConfig.FunctionCodeStartPos + SystemConfig.FunctionCodeLength);


            //前面的,回复用的
            string resp = receiveCmd.Substring(0, pos);

            //消息长度
            int msgLen = Utils.hexToTen(receiveCmd.Substring(pos, SystemConfig.LengthFieldLength * 2));
            pos += SystemConfig.LengthFieldLength * 2;

            //测量点&消息流水
            int msgFlowLength = (SystemConfig.MeasurePointLen + SystemConfig.MessageFlowLen);
            string msgFlow = receiveCmd.Substring(pos, msgFlowLength * 2);

            pos += msgFlowLength * 2;

            Console.WriteLine(resp);
            Console.WriteLine("长度:" + msgLen);
            Console.WriteLine("消息流水:" + msgFlow);
            string bodyFrame = "";

            string tip = "";
            if (wb.mode.Trim().ToUpper().Equals("W"))
            {
                bodyFrame = WriteMessage(receiveCmd, wb, cmdId, msgLen, msgFlow, msgFlowLength, pos);
                tip = "设置回复";
            }
            else if (wb.mode.Trim().ToUpper().Equals("R"))
            {
                //读
                bodyFrame = ReadMessage(wb, msgFlow);
                tip = "读取回复";
            }
            else
            {
                return null;
            }


            resp += bodyFrame;
            resp += CmdUtil.CalcCrc16CodeSkip(resp, 3);
            Console.WriteLine("回复:" + resp);
            DataModel.ReceCollection.Add(new UIInfoModel(tip, resp).setSendType(SystemConfig.SendType));
            return resp;
        }

        private string ReadMessage(WvBean wb, string msgFlow)
        {
            string content = msgFlow + wb.userValue.Trim();
            if (content.Length % 2 != 0)
            {
                content = "0" + content;
            }
            string lenHex =
                CmdUtil.FrontWithZero(Utils.tenToHex(content.Length / 2), SystemConfig.LengthFieldLength * 2);
            return lenHex + content;
        }

        private string WriteMessage(string receiveCmd, WvBean wb, int funWord, int msgLen, string msgFlow,
            int msgFlowLength, int pos)
        {
            try
            {
                int contentLen = msgLen - msgFlowLength;
                string content = receiveCmd.Substring(pos, contentLen * 2);
                Console.WriteLine("下发的内容是:" + content);

                int updateId = funWord;
                if (!wb.remark.Trim().Equals(""))
                {
                    updateId = int.Parse(wb.remark.Trim());
                }

                Console.WriteLine("更新Id=" + updateId + ";内容长度=" + contentLen);
                Console.WriteLine("内容=" + content);

                WvBean updateBean = DbHelper.GetInstance().SelectOneCmdByIndex(updateId);
                if (updateBean != null)
                {
                    updateBean.userValue = content;
                    int result = DbHelper.GetInstance().UpdateCmd(updateBean);
                    if (result > 0)
                    {
                        DataModel.ReceCollection.Add(
                            new UIInfoModel("设置成功.更新=(" + updateId + ") ;16进制=(" +
                                            Utils.tenToHex(updateId) + "); 内容=" + content)
                                .setAction(-1)
                                .setSendType(SystemConfig.ReplyType));
                        return "03" + msgFlow + "00";
                    }
                }
                //不存在这样的Key
                DataModel.ReceCollection.Add(
                    new UIInfoModel("设置失败.本地数据库没有这样的功能码=(" + updateId + ") ;16进制=(" +
                                    Utils.tenToHex(updateId) + ")")
                        .setAction(-1)
                        .setSendType(SystemConfig.ReplyType));
            }
            catch (Exception exception)
            {
                DataModel.ReceCollection.Add(
                    new UIInfoModel("设置数据时,出错." + exception.Message)
                        .setAction(-1)
                        .setSendType(SystemConfig.ReplyType));
            }
            return "03" + msgFlow + "01";
        }
    }
}