using SlnMesnac.RfidUpload.Common;
using SlnMesnac.RfidUpload.Model;
using SlnMesnac.RfidUpload.NLog;
using System;
using System.Text;

namespace SlnMesnac.RfidUpload.Analysis
{
    /// <summary>
    /// 指令适配器
    /// </summary>
    public class InstructionAdapter
    {
        private MsgUtil _msgUtil = MsgUtil.Instance;
        private readonly LogHelper logger = LogHelper.Instance;
        #region 单例实现
        private static readonly Lazy<InstructionAdapter> _lazy = new Lazy<InstructionAdapter>(() => new InstructionAdapter());

        public static InstructionAdapter Instance
        {
            get
            {
                return _lazy.Value;
            }
        }
        #endregion

        private InstructionAdapter() { }

        /// <summary>
        /// 标签解析
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentException"></exception>
        public InstructionInfo ParseInstruction(byte[] buffer)
        {
            logger.Info("开始解析标签信息");
            byte[] m_length = new byte[2];
            Array.Copy(buffer, 2, m_length, 0, 2);
            int bufferLength = Convert.ToInt32(BitConverter.ToString(m_length).Replace("-", ""), 16);

            if (buffer.Length != bufferLength)
            {
                throw new ArgumentException("指令长度不正确");
            }

            byte[] xorbuffer = new byte[buffer.Length - 3];
            Array.Copy(buffer, 2, xorbuffer, 0, xorbuffer.Length);
            string xorStr = _msgUtil.CalculateXORChecksum(xorbuffer);
            string bufferXor = buffer[buffer.Length - 1].ToString("X2");
            if (bufferXor != xorStr)
            {
                throw new ArgumentException($"XOR校验失败,指令XOR:{bufferXor},计算XOR:{xorStr}");
            }

            InstructionInfo instructionInfo = new InstructionInfo();
            byte[] m_stx = new byte[2];
            Array.Copy(buffer, 0, m_stx, 0, 2);
            instructionInfo.stx = BitConverter.ToString(m_stx).Replace("-", "");

            instructionInfo.len = bufferLength;

            instructionInfo.cmd = buffer[4];

            int status = Convert.ToInt32(buffer[5]);
            instructionInfo.status = status;

            byte[] m_data = new byte[bufferLength - 7];
            Array.Copy(buffer, 6, m_data, 0, m_data.Length);
            string dataValue = Encoding.ASCII.GetString(m_data);
            instructionInfo.data = dataValue;

            instructionInfo.xor = buffer[buffer.Length - 1];

            instructionInfo.recordtime = DateTime.Now;

            return instructionInfo;
        }


    }

}