using SuperSocket.ProtoBase;
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Waste.SocketService
{
    /// <summary>
    /// 转换工具
    /// </summary>
    public static class Tools
    {
        public static string GetString(in this ReadOnlySequence<byte> payload,
    Encoding encoding = null)
        {
            encoding ??= Encoding.UTF8;
            return payload.IsSingleSegment ? encoding.GetString(payload.FirstSpan)
                : GetStringSlow(payload, encoding);

            static string GetStringSlow(in ReadOnlySequence<byte> payload, Encoding encoding)
            {
                // linearize
                int length = checked((int)payload.Length);
                var oversized = ArrayPool<byte>.Shared.Rent(length);
                try
                {
                    payload.CopyTo(oversized);
                    return encoding.GetString(oversized, 0, length);
                }
                finally
                {
                    ArrayPool<byte>.Shared.Return(oversized);
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="bt"></param>
        /// <returns></returns>
        public static string ByteToHexStr(this byte bt)
        {
            return bt.ToString("X2");
        }
        /// <summary>
        /// byte转int
        /// </summary>
        /// <param name="bt"></param>
        /// <returns></returns>
        public static int ByteToInt(this byte bt)
        {
            return Convert.ToInt32(((int)bt).ToString("X2"), 16);
        }
        /// <summary>
        /// 字节数组转16进制
        /// </summary>
        /// <param name="bt"></param>
        /// <returns></returns>
        public static string BytesToHexStr(this byte[] bt)
        {
            string returnStr = "";
            if (bt != null)
            {
                for (int i = 0; i < bt.Length; i++)
                {
                    returnStr += bt[i].ToString("X2") + " ";
                }
            }
            return returnStr;
        }
        /// <summary>
        /// 字节数组转字符串
        /// </summary>
        /// <param name="bt"></param>
        /// <returns></returns>
        public static string BytesToString(this byte[] bytes)
        {
            string returnStr = "";
            if (bytes != null)
            {
                returnStr = Encoding.GetEncoding("GB2312").GetString(bytes);
            }
            return returnStr;
        }
        /// <summary>
        /// 字节数组转字符串
        /// </summary>
        /// <param name="bt"></param>
        /// <returns></returns>
        public static string BytesToStringBUtf8(this byte[] bytes)
        {
            string returnStr = "";
            if (bytes != null)
            {
                returnStr = Encoding.UTF8.GetString(bytes);
            }
            return returnStr;
        }
        /// <summary>
        /// 字节数据转中文
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static string BytesToChsString(this byte[] bytes)
        {
            string hex = BytesToHexStr(bytes);
            if (hex == null)
                return "";
            if (hex.Length % 2 != 0)
            {
                hex += "20";//空格
            }
            for (int i = 0; i < bytes.Length; i++)
            {
                try
                {
                    // 每两个字符是一个 byte。
                    bytes[i] = byte.Parse(hex.Substring(i * 2, 2),
                        System.Globalization.NumberStyles.HexNumber);
                }
                catch
                {
                }
            }
            // 获得 GB2312，Chinese Simplified。
            Encoding chs = Encoding.GetEncoding("gb2312");
            return chs.GetString(bytes);
        }

        /// <summary>
        /// 16进制转10进制
        /// </summary>
        /// <param name="hex"></param>
        /// <returns></returns>
        public static long HextToDec(this string hex)
        {
            char[] nums = hex.ToCharArray();
            long total = 0;
            try
            {
                for (int i = 0; i < nums.Length; i++)
                {
                    String strNum = nums[i].ToString().ToUpper();
                    switch (strNum)
                    {
                        case "A":
                            strNum = "10";
                            break;
                        case "B":
                            strNum = "11";
                            break;
                        case "C":
                            strNum = "12";
                            break;
                        case "D":
                            strNum = "13";
                            break;
                        case "E":
                            strNum = "14";
                            break;
                        case "F":
                            strNum = "15";
                            break;
                        default:
                            break;
                    }
                    double power = Math.Pow(16, Convert.ToDouble(nums.Length - i - 1));
                    total += Convert.ToInt64(strNum) * Convert.ToInt64(power);
                }

            }
            catch (System.Exception ex)
            {
                string strErorr = ex.ToString();
                return 0;
            }


            return total;
        }

    }
    /// <summary>
    /// 垃圾分类格式解析,传输过来的数据格式类似于:九方城@前门@厨余垃圾@7.91
    /// </summary>
    public class WastePackageFilter : PipelineFilterBase<MyPackage>
    {
        public override MyPackage Filter(ref SequenceReader<byte> reader)
        {
            try
            {
                if (reader.Length <= 0)
                {
                    return null;
                }
                var package = new MyPackage();
                var _reader = reader;
                Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
                string key = "";
                int keylen = 1;
                #region 解析头部，头部固定为A9
                if (reader.Length >= 2)
                {
                    keylen = 2;
                    byte[] keys = new byte[2];
                    reader.TryRead(out byte key1Byte);
                    keys[0] = key1Byte;
                    reader.TryRead(out byte key2Byte);
                    keys[1] = key2Byte;
                    key = keys.BytesToString();
                }
                else
                {
                    byte[] keys = new byte[1];
                    reader.TryRead(out byte key1Byte);
                    keys[0] = key1Byte;
                    key = keys.BytesToString();
                }
                #endregion
                if (key != "A9" && key !="A8")
                {
                    package.Str = _reader.ReadString(Encoding.GetEncoding("GB2312"));
                    var len = reader.Length;
                    string msg = "";
                    reader.Rewind(keylen);
                    for (var i = 0; i < len; i++)
                    {
                        reader.TryRead(out byte msgByte);
                        msg += msgByte.ByteToHexStr();
                    }
                    package.IsChecked = false;
                    package.Body = msg;
                }
                else if (key == "A8")
                {
                    package.Key = key;
                    package.Len = (int)reader.Length - 2;
                    string body = "";
                    byte[] bytes = new byte[package.Len];
                    for (var i = 0; i < package.Len; i++)
                    {
                        reader.TryRead(out byte val);
                        bytes[i] = val;
                    }
                    if (bytes.Length == 1 && bytes[0] == 0)
                    {
                        return null;
                    }
                    body = bytes.BytesToStringBUtf8().Replace("\r", "").Replace("\n", "");
                    package.Body = bytes.BytesToHexStr();
                    var arr = body.Split('|');
                    #region 心跳包的处理,IMEI|GPS
                    if (arr.Length == 2)
                    {
                        package.IsHeart = true;
                        package.IMEI = arr[0];
                        var gpsarr = arr[1].Split(',');
                        if (gpsarr.Length == 2)
                        {
                            package.Longitude = gpsarr[0];
                            package.Latitude = gpsarr[1];
                        }
                    }
                    else if (arr.Length == 7 && string.IsNullOrEmpty(arr[6]))
                    {
                        package.IsHeart = true;
                        package.ICCID = arr[0];
                        package.IMEI = arr[1];
                        package.IMSI = arr[2];
                        var gslq = Encoding.GetEncoding("GB2312").GetBytes(arr[3]);
                        if (gslq.Length == 2)
                        {
                            package.GSLQ = Convert.ToInt32(gslq[1]).ToString();
                        }
                        else
                        {
                            package.GSLQ = gslq.BytesToHexStr();
                        }
                        package.Time = $"{arr[4]}{arr[5]}".Replace("-", "").Replace(":", "");
                    }
                    else if (arr.Length == 7)
                    {
                        package.ICCID = arr[0];
                        package.IMEI = arr[1];
                        package.IMSI = arr[2];
                        var gslq = Encoding.GetEncoding("GB2312").GetBytes(arr[3]);
                        if (gslq.Length == 2)
                        {
                            package.GSLQ = Convert.ToInt32(gslq[1]).ToString();
                        }
                        else
                        {
                            package.GSLQ = gslq.BytesToHexStr();
                        }
                        package.Time = $"{arr[4]}{arr[5]}".Replace("-", "").Replace(":", "");
                        //uuid@datetime@垃圾类型@子类@重量@价格@金额@操作员
                        package.Str = _reader.ReadString(Encoding.UTF8);
                        var measurearr = arr[6].Split('@');
                        if (measurearr.Length == 8)
                        {
                            package.UUID = measurearr[0];
                            package.UploadTime = measurearr[1];
                            package.WasteType = measurearr[2];
                            package.WasteSType = measurearr[3];
                            package.Weight = measurearr[4];
                            package.Price = measurearr[5];
                            package.Amount = measurearr[6];
                            package.OpUser = measurearr[7];
                            package.IsWeight = true;
                        }
                        else
                        {
                            package.size = arr[6];
                        }

                    }
                    #endregion
                }
                else
                {
                    package.Str = _reader.ReadString(Encoding.GetEncoding("GB2312"));
                    package.Key = key;
                    package.Len = (int)reader.Length - 2;
                    string body = "";
                    byte[] bytes = new byte[package.Len];
                    for (var i = 0; i < package.Len; i++)
                    {
                        reader.TryRead(out byte val);
                        bytes[i] = val;
                    }
                    if (bytes.Length == 1 && bytes[0] == 0)
                    {
                        return null;
                    }
                    body = bytes.BytesToString().Replace("\r", "").Replace("\n", "");
                    package.Body = bytes.BytesToHexStr();
                    var arr = body.Split('|');
                    #region 心跳包的处理,IMEI|GPS
                    if (arr.Length == 2)
                    {
                        package.IsHeart = true;
                        package.IMEI = arr[0];
                        var gpsarr = arr[1].Split(',');
                        if (gpsarr.Length == 2)
                        {
                            package.Longitude = gpsarr[0];
                            package.Latitude = gpsarr[1];
                        }
                    }
                    else if (arr.Length == 7 && string.IsNullOrEmpty(arr[6]))
                    {
                        package.IsHeart = true;
                        package.ICCID = arr[0];
                        package.IMEI = arr[1];
                        package.IMSI = arr[2];
                        var gslq = Encoding.GetEncoding("GB2312").GetBytes(arr[3]);
                        if (gslq.Length == 2)
                        {
                            package.GSLQ = Convert.ToInt32(gslq[1]).ToString();
                        }
                        else
                        {
                            package.GSLQ = gslq.BytesToHexStr();
                        }
                        package.Time = $"{arr[4]}{arr[5]}".Replace("-", "").Replace(":", "");
                    }
                    else if (arr.Length == 7)
                    {
                        package.ICCID = arr[0];
                        package.IMEI = arr[1];
                        package.IMSI = arr[2];
                        var gslq = Encoding.GetEncoding("GB2312").GetBytes(arr[3]);
                        if (gslq.Length == 2)
                        {
                            package.GSLQ = Convert.ToInt32(gslq[1]).ToString();
                        }
                        else
                        {
                            package.GSLQ = gslq.BytesToHexStr();
                        }
                        package.Time = $"{arr[4]}{arr[5]}".Replace("-", "").Replace(":", "");
                        //厨余垃圾/大桶@垃圾桶编号@厨余垃圾@7.91
                        var b = Encoding.GetEncoding("GB2312").GetBytes(arr[6]);
                        if (b.Length > 23)
                        {
                            byte[] tbyte = new byte[1]; //桶类型
                            byte[] codebyte = new byte[5];//垃圾桶编号
                            byte[] typebyte = new byte[8];//垃圾类型
                            byte[] wbyte = new byte[b.Length - 23];
                            byte[] db = new byte[b.Length - 8];
                            for (var j = 0; j < b.Length; j++)
                            {
                                if (j == 6)
                                {
                                    tbyte[j - 6] = b[j];
                                }
                                else if (j > 7 && j < 13)
                                {
                                    codebyte[j - 8] = b[j];
                                }
                                else if (j > 13 && j < 22)
                                {
                                    typebyte[j - 14] = b[j];
                                }
                                else if (j > 22)
                                {
                                    wbyte[j - 23] = b[j];
                                }
                            }
                            var thex = tbyte.BytesToHexStr();
                            var codehex = codebyte.BytesToHexStr();
                            var typehex = typebyte.BytesToHexStr();
                            var typestr = typebyte.BytesToString();
                            var whex = wbyte.BytesToHexStr();
                            var wstr = wbyte.BytesToString();
                            package.size = thex.Replace(" ", "");
                            package.trashcode = codehex.Replace(" ", "").HextToDec().ToString();
                            package.WasteType = typestr;
                            package.Weight = wstr;
                            package.IsWeight = true;
                        }
                        else
                        {
                            package.size = arr[6];
                        }

                    }
                    #endregion
                }
                return package;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"数据处理发生异常:{ex.Message}");
                return new MyPackage();
            }
        }
    }
}
