using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using log4net;
using System.IO.Ports;
using System.Net;

namespace ChuPiao.Common.Utils
{
    public class ComPortClient
    {
        public ComPortClient(string port, int portBps,Encoding encoding)
        {
            _port = port;
            _portBps = portBps;
            _com = new SerialPort(_port, _portBps, Parity.None);
            _charset = encoding;
        }

        private Encoding _charset;
        private SerialPort _com;
        private string _port;
        private int _portBps;

        /// <summary>
        /// 启动
        /// </summary>
        public void Start()
        {
            try
            {
                if (_com == null)
                {
                    _com = new SerialPort(_port, _portBps, Parity.None);
                }
                if (!_com.IsOpen)
                {
                    _com.Open();
                }
            }
            catch (Exception exception)
            {
                throw new Exception(string.Concat("串口启动异常：", exception.Message));
            }
            
        }

        /// <summary>
        /// 停止
        /// </summary>
        public void Stop()
        {
            if (_com != null)
            {
                if (_com.IsOpen)
                {
                    _com.Close();
                }
                _com.Dispose();
            }
        }

        /// <summary>
        /// 发送消息包
        /// </summary>
        /// <param name="message"></param>
        private void Send(string message)
        {
            byte[] contentData = _charset.GetBytes(message);
            //因为BitConverter.GetBytes是按小端字节序转换成byte数组，而网络字节序是大端字节序，所以进行转换
            byte[] headerData = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(contentData.Length));
            _com.Write(headerData, 0, headerData.Length);
            _com.Write(contentData, 0, contentData.Length);
        }

        /// <summary>
        /// 读取回复消息包
        /// </summary>
        /// <returns></returns>
        private string Read()
        {
            while (_com.BytesToRead <= 0)
            {
                Thread.Sleep(100);
            }
            string content = string.Empty;

            byte[] buffer = new byte[4];
            _com.Read(buffer, 0, buffer.Length);
            //因为BitConverter.GetBytes是按小端字节序转换成byte数组，而网络字节序是大端字节序，所以进行转换
            int contentLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(buffer, 0));
            if (contentLength > 0)
            {
                byte[] contentData = new byte[contentLength];

                int offset = 0;
                int num = 0;
                do
                {
                    num = _com.Read(contentData, offset, contentLength - offset);
                    offset += num;
                } while (num > 0 && offset < contentLength);
                if (offset != contentLength)
                {
                    throw new Exception("交易包长度与实际交易内容长度不符");
                }
                content = _charset.GetString(contentData);
            }

            return content;
        }

        /// <summary>
        /// 提交请求
        /// </summary>
        /// <param name="requestMsg"></param>
        /// <returns></returns>
        public string CommitRequest(string requestMsg)
        {
            lock (this)
            {
                try
                {
                    Start();
                    Send(requestMsg);
                    string returnstr = Read();
                    if (_com.IsOpen) ;
                    return returnstr;
                }
                catch (Exception e)
                {
                    throw new Exception(string.Concat("串口通讯异常：", e));
                }
            }
        }

    }
}