using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MWS.Domain.Dto
{
    public class SerialClient : IDisposable
    {
        SerialPort serialPort;
        public SerialClient(string portName, int baudRate = 4800, Parity parity = Parity.None, int dataBits = 8, StopBits stopBits = StopBits.One)
        {
            serialPort = new SerialPort();
            serialPort.PortName = portName;
            serialPort.BaudRate = baudRate;
            serialPort.DataBits = dataBits;
            serialPort.StopBits = stopBits;
            serialPort.Parity = parity;

        }
        public SerialClient OpenSerial()
        {
            try
            {
                serialPort.Open();
            }
            catch
            {
                Console.WriteLine("打开串口失败，10秒后重试！");
                SleepAndReconnect();
            }
            return this;
        }
        public void ClosedSerial()
        {
            try
            {
                serialPort?.Close();
            }
            catch
            {
                Console.WriteLine("关闭串口失败");
            }
        }
        public void SendData(ushort weight)
        {
            if (serialPort.IsOpen)
            {
                var weightByte = BitConverter.GetBytes(weight).Reverse().ToArray();
                byte[] data = new byte[8] { 0x3A, 0x01, 0x08, 0x42, 0x02, weightByte[1], weightByte[0], 0x00 };
                data[7] = GetLRC(data, 7);
                serialPort.Write(data, 0, 8);
            }

        }
        private byte GetLRC(byte[] buff, int length)
        {
            byte[] check_sum = new byte[2] { 0, 0 };
            for (int i = 0; i < length; i++)
                check_sum[0] += buff[i];
            check_sum[1] = (byte)(~check_sum[0] + 1);
            return check_sum[1];
        }
        private void SleepAndReconnect()
        {
            ThreadPool.QueueUserWorkItem(action =>
            {
                Thread.Sleep(10000);
                if (!serialPort.IsOpen)
                {
                    OpenSerial();
                }
            });
        }

        public void Dispose()
        {
            serialPort?.Close();
            serialPort.Dispose();
        }
    }
}
