using HslCommunication;
using HslCommunication.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ProjectManagementSystem.Common.Extenions
{
    public static class IReadWriteNetExtenions
    {
        public static OperateResult WriteValue<T>(this IReadWriteNet plc, string plcAddr, T plcValue)
        {
            OperateResult operateResult;
            switch (plcValue)
            {
                case bool value:
                    operateResult = plc.Write(plcAddr, value);
                    break;
                case byte value:
                    operateResult = plc.Write(plcAddr, new byte[] { value });
                    break;
                case short value:
                    operateResult = plc.Write(plcAddr, value);
                    break;
                case ushort value:
                    operateResult = plc.Write(plcAddr, value);
                    break;
                case int value:
                    operateResult = plc.Write(plcAddr, value);
                    break;
                case uint value:
                    operateResult = plc.Write(plcAddr, value);
                    break;
                case long value:
                    operateResult = plc.Write(plcAddr, value);
                    break;
                case ulong value:
                    operateResult = plc.Write(plcAddr, value);
                    break;
                case string value:
                    operateResult = plc.Write(plcAddr, value, Encoding.ASCII);
                    break;
                default:
                    operateResult = new OperateResult($"未识别的数据类型 {typeof(T).Name}");
                    operateResult.IsSuccess = false;
                    break;
            }

            return operateResult;
        }

        public static bool ReadValue<T>(this IReadWriteNet plc, string plcAddr, T plcValue, out OperateResult<T> operateResult)
        {
            operateResult = new OperateResult<T>();

            switch (plcValue)
            {
                case bool value:
                    {
                        var readResult = plc.ReadBool(plcAddr);
                        operateResult.IsSuccess = readResult.IsSuccess;
                        operateResult.Content = readResult.Content.ToValue<T>();
                        operateResult.Message = readResult.Message;
                        if (readResult.IsSuccess
                            && readResult.Content == value)
                        {
                            return true;
                        }
                    }
                    break;
                case byte value:
                    {
                        var readResult = plc.Read(plcAddr, 1);
                        operateResult.IsSuccess = readResult.IsSuccess;
                        operateResult.Content = readResult.Content[0].ToValue<T>();
                        operateResult.Message = readResult.Message;
                        if (readResult.IsSuccess
                            && readResult.Content[0] == value)
                        {
                            return true;
                        }
                    }
                    break;
                case short value:
                    {
                        var readResult = plc.ReadInt16(plcAddr);
                        operateResult.IsSuccess = readResult.IsSuccess;
                        operateResult.Content = readResult.Content.ToValue<T>();
                        operateResult.Message = readResult.Message;
                        if (readResult.IsSuccess
                            && readResult.Content == value)
                        {
                            return true;
                        }
                    }
                    break;
                case ushort value:
                    {
                        var readResult = plc.ReadUInt16(plcAddr);
                        operateResult.IsSuccess = readResult.IsSuccess;
                        operateResult.Content = readResult.Content.ToValue<T>();
                        operateResult.Message = readResult.Message;
                        if (readResult.IsSuccess
                            && readResult.Content == value)
                        {
                            return true;
                        }
                    }
                    break;
                case int value:
                    {
                        var readResult = plc.ReadInt32(plcAddr);
                        operateResult.IsSuccess = readResult.IsSuccess;
                        operateResult.Content = readResult.Content.ToValue<T>();
                        operateResult.Message = readResult.Message;
                        if (readResult.IsSuccess
                            && readResult.Content == value)
                        {
                            return true;
                        }
                    }
                    break;
                case uint value:
                    {
                        var readResult = plc.ReadUInt32(plcAddr);
                        operateResult.IsSuccess = readResult.IsSuccess;
                        operateResult.Content = readResult.Content.ToValue<T>();
                        operateResult.Message = readResult.Message;
                        if (readResult.IsSuccess
                            && readResult.Content == value)
                        {
                            return true;
                        }
                    }
                    break;
                case long value:
                    {
                        var readResult = plc.ReadInt64(plcAddr);
                        operateResult.IsSuccess = readResult.IsSuccess;
                        operateResult.Content = readResult.Content.ToValue<T>();
                        operateResult.Message = readResult.Message;
                        if (readResult.IsSuccess
                            && readResult.Content == value)
                        {
                            return true;
                        }
                    }
                    break;
                case ulong value:
                    {
                        var readResult = plc.ReadUInt64(plcAddr);
                        operateResult.IsSuccess = readResult.IsSuccess;
                        operateResult.Content = readResult.Content.ToValue<T>();
                        operateResult.Message = readResult.Message;
                        if (readResult.IsSuccess
                            && readResult.Content == value)
                        {
                            return true;
                        }
                    }
                    break;
                case string value:
                    {
                        var readResult = plc.ReadString(plcAddr, (ushort)value.Length, Encoding.ASCII);
                        operateResult.IsSuccess = readResult.IsSuccess;
                        operateResult.Content = readResult.Content.ToValue<T>();
                        operateResult.Message = readResult.Message;
                        if (readResult.IsSuccess
                            && readResult.Content == value)
                        {
                            return true;
                        }
                    }
                    break;
                default:
                    operateResult.IsSuccess = false;
                    operateResult.Content = default(T);
                    operateResult.Message = $"未识别的数据类型 {typeof(T).Name}";
                    break;
            }

            return false;
        }


        //public static OperateResult WriteValue<T>(this IReadWriteNet plc, string plcAddr, T plcValue)
        //{
        //    string DbValueTypeName = typeof(T).Name;
        //    OperateResult operateResult = null;
        //    switch (DbValueTypeName)
        //    {
        //        case "Boolean":
        //            operateResult = plc.Write(plcAddr, plcValue.ToValue<bool>());
        //            break;
        //        case "Byte":
        //            var dbValue = plcValue.ToValue<byte>();
        //            operateResult = plc.Write(plcAddr, new byte[] { dbValue });
        //            break;
        //        case "Int16":
        //            operateResult = plc.Write(plcAddr, plcValue.ToValue<short>());
        //            break;
        //        case "UInt16":
        //            operateResult = plc.Write(plcAddr, plcValue.ToValue<ushort>());
        //            break;
        //        case "Int32":
        //            operateResult = plc.Write(plcAddr, plcValue.ToValue<int>());
        //            break;
        //        case "UInt32":
        //            operateResult = plc.Write(plcAddr, plcValue.ToValue<uint>());
        //            break;
        //        case "Int64":
        //            operateResult = plc.Write(plcAddr, plcValue.ToValue<long>());
        //            break;
        //        case "UInt64":
        //            operateResult = plc.Write(plcAddr, plcValue.ToValue<ulong>());
        //            break;
        //        case "String":
        //            operateResult = plc.Write(plcAddr, plcValue.ToValue<string>(), Encoding.ASCII);
        //            break;
        //        default:
        //            operateResult = new OperateResult($"未识别的数据类型 {DbValueTypeName}");
        //            operateResult.IsSuccess = false;
        //            break;
        //    }

        //    return operateResult;
        //}

        //public static bool ReadValue<T>(this IReadWriteNet plc, string plcAddr, T plcValue, out OperateResult<T> operateResult)
        //{
        //    string DbValueTypeName = typeof(T).Name;
        //    operateResult = new OperateResult<T>();

        //    switch (DbValueTypeName)
        //    {
        //        case "Boolean":
        //            {
        //                var readResult = plc.ReadBool(plcAddr);
        //                operateResult.IsSuccess = readResult.IsSuccess;
        //                operateResult.Content = readResult.Content.ToValue<T>();
        //                operateResult.Message = readResult.Message;
        //                if (readResult.IsSuccess
        //                    && readResult.Content == plcValue.ToValue<bool>())
        //                {
        //                    return true;
        //                }
        //            }
        //            break;
        //        case "Byte":
        //            {
        //                var readResult = plc.Read(plcAddr, 1);
        //                operateResult.IsSuccess = readResult.IsSuccess;
        //                operateResult.Content = readResult.Content[0].ToValue<T>();
        //                operateResult.Message = readResult.Message;
        //                if (readResult.IsSuccess
        //                    && readResult.Content[0] == plcValue.ToValue<byte>())
        //                {
        //                    return true;
        //                }
        //            }
        //            break;
        //        case "Int16":
        //            {
        //                var readResult = plc.ReadInt16(plcAddr);
        //                operateResult.IsSuccess = readResult.IsSuccess;
        //                operateResult.Content = readResult.Content.ToValue<T>();
        //                operateResult.Message = readResult.Message;
        //                if (readResult.IsSuccess
        //                    && readResult.Content == plcValue.ToValue<short>())
        //                {
        //                    return true;
        //                }
        //            }
        //            break;
        //        case "UInt16":
        //            {
        //                var readResult = plc.ReadUInt16(plcAddr);
        //                operateResult.IsSuccess = readResult.IsSuccess;
        //                operateResult.Content = readResult.Content.ToValue<T>();
        //                operateResult.Message = readResult.Message;
        //                if (readResult.IsSuccess
        //                    && readResult.Content == plcValue.ToValue<ushort>())
        //                {
        //                    return true;
        //                }
        //            }
        //            break;
        //        case "Int32":
        //            {
        //                var readResult = plc.ReadInt32(plcAddr);
        //                operateResult.IsSuccess = readResult.IsSuccess;
        //                operateResult.Content = readResult.Content.ToValue<T>();
        //                operateResult.Message = readResult.Message;
        //                if (readResult.IsSuccess
        //                    && readResult.Content == plcValue.ToValue<int>())
        //                {
        //                    return true;
        //                }
        //            }
        //            break;
        //        case "UInt32":
        //            {
        //                var readResult = plc.ReadUInt32(plcAddr);
        //                operateResult.IsSuccess = readResult.IsSuccess;
        //                operateResult.Content = readResult.Content.ToValue<T>();
        //                operateResult.Message = readResult.Message;
        //                if (readResult.IsSuccess
        //                    && readResult.Content == plcValue.ToValue<uint>())
        //                {
        //                    return true;
        //                }
        //            }
        //            break;
        //        case "Int64":
        //            {
        //                var readResult = plc.ReadInt64(plcAddr);
        //                operateResult.IsSuccess = readResult.IsSuccess;
        //                operateResult.Content = readResult.Content.ToValue<T>();
        //                operateResult.Message = readResult.Message;
        //                if (readResult.IsSuccess
        //                    && readResult.Content == plcValue.ToValue<long>())
        //                {
        //                    return true;
        //                }
        //            }
        //            break;
        //        case "UInt64":
        //            {
        //                var readResult = plc.ReadUInt64(plcAddr);
        //                operateResult.IsSuccess = readResult.IsSuccess;
        //                operateResult.Content = readResult.Content.ToValue<T>();
        //                operateResult.Message = readResult.Message;
        //                if (readResult.IsSuccess
        //                    && readResult.Content == plcValue.ToValue<ulong>())
        //                {
        //                    return true;
        //                }
        //            }
        //            break;
        //        case "String":
        //            {
        //                string plcValueContent = plcValue.ToValue<string>();

        //                var readResult = plc.ReadString(plcAddr, (ushort)plcValueContent.Length, Encoding.ASCII);
        //                operateResult.IsSuccess = readResult.IsSuccess;
        //                operateResult.Content = readResult.Content.ToValue<T>();
        //                operateResult.Message = readResult.Message;
        //                if (readResult.IsSuccess
        //                    && readResult.Content == plcValueContent)
        //                {
        //                    return true;
        //                }
        //            }
        //            break;
        //        default:
        //            operateResult.IsSuccess = false;
        //            operateResult.Content = 0.ToValue<T>();
        //            operateResult.Message = $"未识别的数据类型 {DbValueTypeName}";
        //            break;
        //    }

        //    return false;
        //}
    }
}
