using System;
using System.Threading.Tasks;
using HighWayIot.Log4net;
using HslCommunication;
using HslCommunication.Profinet.Melsec;

namespace HighWayIot.Plc
{
    public class PlcConnect
    {
        //private static readonly Lazy<PlcConnect> lazy = new Lazy<PlcConnect>(() => new PlcConnect());

        //public static PlcConnect Instance
        //{
        //    get
        //    {
        //        return lazy.Value;
        //    }
        //}

        private static LogHelper logHelper = LogHelper.Instance;

        /// <summary>
        /// 静态懒加载MelsecMcNet1 开炼机CPU
        /// </summary>
        //public static readonly MelsecMcNet MelsecInstance1 = new PlcConnect().CreateAb("10.20.48.40");
        //public static readonly MelsecMcNet MelsecInstance1 = new PlcConnect().CreateAb("127.0.0.1");

        /// <summary>
        /// 静态懒加载MelsecMcNet2 成型机CPU
        /// </summary>
        public static readonly MelsecMcNet MelsecInstance2 = CreateAb("10.20.48.10");

        private PlcConnect()
        {

        }

        /// <summary>
        /// 初始化三菱的服务器
        /// </summary>
        /// <returns></returns>
        private static MelsecMcNet CreateAb(string ip)
        {
            //string Ip = ;
            MelsecMcNet plc = new MelsecMcNet();
            try
            {
                plc.CommunicationPipe = new HslCommunication.Core.Pipe.PipeTcpNet(ip, 2001)
                {
                    ConnectTimeOut = 3000,    // 连接超时时间，单位毫秒
                    ReceiveTimeOut = 2000,   // 接收超时时间，单位毫秒
                    SleepTime = 0,
                    SocketKeepAliveTime = -1,
                    IsPersistentConnection = true,
                };

                OperateResult result;
                result = plc.ConnectServer();
                logHelper.Info($"Plc连接 信息：[{result.Message}] 错误代码：[{result.ErrorCode}]");
                
            }
            catch (Exception ex)
            {
                logHelper.Error("初始化PLC服务器发生错误！", ex);
            }

            return plc;
        }

        ///// <summary>
        ///// plc1 是不是保持链接
        ///// </summary>
        //public static bool IsConnect1
        //{
        //    get
        //    {
        //        if (MelsecInstance1 == null) return false;
        //        var result = MelsecInstance1.ReadBool("B0").IsSuccess;
        //        logHelper.Info($"PLC[{MelsecInstance1.IpAddress}]连接：[{(result ? "正常" : "异常")}]");
        //        return result;
        //    }
        //}

        ///// <summary>
        ///// plc2 是不是保持链接
        ///// </summary>
        //public static bool IsConnect2
        //{
        //    get
        //    {
        //        if (MelsecInstance2 == null) return false;
        //        var result = MelsecInstance2.ReadBool("D100").IsSuccess;
        //        logHelper.Info($"PLC[{MelsecInstance2.IpAddress}]连接：[{(result ? "正常" : "异常")}]");
        //        return result;
        //    }
        //}

        ///// <summary>
        ///// PLC1写入数据
        ///// </summary>
        ///// <param name="address">地址</param>
        ///// <param name="value">值</param>
        ///// <param name="type">数据类型</param>
        ///// <returns></returns>
        //public static OperateResult PlcWrite1(string address, object value, DataTypeEnum type)
        //{
        //    var result = new OperateResult() { IsSuccess = false };
        //    if (value == null)
        //    {
        //        return result;
        //    }
        //    try
        //    {
        //        switch (type)
        //        {
        //            case DataTypeEnum.Bool:
        //                result = MelsecInstance1.Write(address, Convert.ToBoolean(value));
        //                break;
        //            //case DataTypeEnum.Byte:
        //            //    result = Instance.Write(address, Convert.ToByte(value));
        //            //    break;
        //            case DataTypeEnum.Int16:
        //                result = MelsecInstance1.Write(address, Convert.ToInt16(value));
        //                break;
        //            case DataTypeEnum.UInt16:
        //                result = MelsecInstance1.Write(address, Convert.ToUInt16(value));
        //                break;
        //            case DataTypeEnum.Int32:
        //                result = MelsecInstance1.Write(address, Convert.ToInt32(value));
        //                break;
        //            case DataTypeEnum.UInt32:
        //                result = MelsecInstance1.Write(address, Convert.ToUInt32(value));
        //                break;
        //            case DataTypeEnum.Int64:
        //                result = MelsecInstance1.Write(address, Convert.ToInt64(value));
        //                break;
        //            case DataTypeEnum.UInt64:
        //                result = MelsecInstance1.Write(address, Convert.ToUInt64(value));
        //                break;
        //            case DataTypeEnum.Float:
        //                result = MelsecInstance1.Write(address, Convert.ToSingle(value));
        //                break;
        //            case DataTypeEnum.Double:
        //                result = MelsecInstance1.Write(address, Convert.ToDouble(value));
        //                break;
        //            case DataTypeEnum.String:
        //                result = MelsecInstance1.Write(address, Convert.ToString(value));
        //                break;
        //            default:
        //                throw new ArgumentException($"Unsupported data type: {type}");
        //        }
        //        logHelper.PlcLog($"Read address:[{address}] value:[{value}] type:[{type.ToString()}] result:[{result.IsSuccess}]");
        //    }
        //    catch (Exception ex)
        //    {
        //        logHelper.Error("PLC写入数据发生错误！", ex);
        //    }
        //    return result;
        //}


        ///// <summary>
        ///// PLC2写入数据
        ///// </summary>
        ///// <param name="address">地址</param>
        ///// <param name="value">值</param>
        ///// <param name="type">数据类型</param>
        ///// <returns></returns>
        //public static OperateResult PlcWrite2(string address, object value, DataTypeEnum type)
        //{
        //    var result = new OperateResult() { IsSuccess = false };
        //    try
        //    {
        //        switch (type)
        //        {
        //            case DataTypeEnum.Bool:
        //                result = MelsecInstance2.Write(address, Convert.ToBoolean(value));
        //                break;
        //            //case DataTypeEnum.Byte:
        //            //    result = Instance.Write(address, Convert.ToByte(value));
        //            //    break;
        //            case DataTypeEnum.Int16:
        //                result = MelsecInstance2.Write(address, Convert.ToInt16(value));
        //                break;
        //            case DataTypeEnum.UInt16:
        //                result = MelsecInstance2.Write(address, Convert.ToUInt16(value));
        //                break;
        //            case DataTypeEnum.Int32:
        //                result = MelsecInstance2.Write(address, Convert.ToInt32(value));
        //                break;
        //            case DataTypeEnum.UInt32:
        //                result = MelsecInstance2.Write(address, Convert.ToUInt32(value));
        //                break;
        //            case DataTypeEnum.Int64:
        //                result = MelsecInstance2.Write(address, Convert.ToInt64(value));
        //                break;
        //            case DataTypeEnum.UInt64:
        //                result = MelsecInstance2.Write(address, Convert.ToUInt64(value));
        //                break;
        //            case DataTypeEnum.Float:
        //                result = MelsecInstance2.Write(address, Convert.ToSingle(value));
        //                break;
        //            case DataTypeEnum.Double:
        //                result = MelsecInstance2.Write(address, Convert.ToDouble(value));
        //                break;
        //            case DataTypeEnum.String:
        //                result = MelsecInstance2.Write(address, Convert.ToString(value));
        //                break;
        //            default:
        //                throw new ArgumentException($"Unsupported data type: {type}");
        //        }
        //        logHelper.PlcLog($"Read address:[{address}] value:[{value}] type:[{type.ToString()}] result:[{result.IsSuccess}]");
        //    }
        //    catch (Exception ex)
        //    {
        //        logHelper.Error("PLC写入数据发生错误！", ex);
        //    }
        //    return result;
        //}

        ///// <summary>
        ///// 字符串读取1
        ///// </summary>
        ///// <param name="address"></param>
        ///// <param name="length"></param>
        ///// <returns></returns>
        //public static string ReadString1(string address, ushort length)
        //{
        //    OperateResult<string> result = new OperateResult<string>();
        //    try
        //    {
        //        result = MelsecInstance1.ReadString(address, length);
        //    }
        //    catch (Exception ex)
        //    {
        //        logHelper.Error($"PLC1读取String发生错误！address:[{address}]", ex);
        //        return default;
        //    }
        //    if (!result.IsSuccess)
        //    {
        //        return default;
        //    }
        //    return result.Content;
        //}

        ///// <summary>
        ///// 读取bool
        ///// </summary>
        ///// <param name="address"></param>
        ///// <returns></returns>
        //public static bool ReadBool1(string address)
        //{
        //    OperateResult<bool> result = new OperateResult<bool>();
        //    try
        //    {
        //        result = MelsecInstance1.ReadBool(address);
        //    }
        //    catch (Exception ex)
        //    {
        //        logHelper.Error($"PLC读取Bool发生错误！address:[{address}]", ex);
        //        return default;
        //    }
        //    if (!result.IsSuccess)
        //    {
        //        return default;
        //    }
        //    return result.Content;
        //}

        ///// <summary>
        ///// 读取Int16
        ///// </summary>
        ///// <param name="address"></param>
        ///// <returns></returns>
        //public static short ReadInt161(string address)
        //{
        //    OperateResult<short> result = new OperateResult<short>();
        //    try
        //    {
        //        result = MelsecInstance1.ReadInt16(address);
        //    }
        //    catch (Exception ex)
        //    {
        //        logHelper.Error($"PLC读取Int16发生错误！address:[{address}]", ex);
        //        return default;
        //    }
        //    if (!result.IsSuccess)
        //    {
        //        return default;
        //    }
        //    return result.Content;
        //}

        ///// <summary>
        ///// 读取UInt16
        ///// </summary>
        ///// <param name="address"></param>
        ///// <returns></returns>
        //public static ushort ReadUInt161(string address)
        //{
        //    OperateResult<ushort> result = new OperateResult<ushort>();
        //    try
        //    {
        //        result = MelsecInstance1.ReadUInt16(address);
        //    }
        //    catch (Exception ex)
        //    {
        //        logHelper.Error($"PLC读取Int16发生错误！address:[{address}]", ex);
        //        return default;
        //    }
        //    if (!result.IsSuccess)
        //    {
        //        return default;
        //    }
        //    return result.Content;
        //}

        ///// <summary>
        ///// 读取Int32
        ///// </summary>
        ///// <param name="address"></param>
        ///// <returns></returns>
        //public static int ReadInt321(string address)
        //{
        //    OperateResult<int> result = new OperateResult<int>();
        //    try
        //    {
        //        result = MelsecInstance1.ReadInt32(address);
        //    }
        //    catch (Exception ex)
        //    {
        //        logHelper.Error($"PLC读取Int16发生错误！address:[{address}]", ex);
        //        return default;
        //    }
        //    if (!result.IsSuccess)
        //    {
        //        return default;
        //    }
        //    return result.Content;
        //}

        ///// <summary>
        ///// 读取UInt32
        ///// </summary>
        ///// <param name="address"></param>
        ///// <returns></returns>
        //public static uint ReadUInt321(string address)
        //{
        //    OperateResult<uint> result = new OperateResult<uint>();
        //    try
        //    {
        //        result = MelsecInstance1.ReadUInt32(address);
        //    }
        //    catch (Exception ex)
        //    {
        //        logHelper.Error($"PLC读取Int16发生错误！address:[{address}]", ex);
        //        return default;
        //    }
        //    if (!result.IsSuccess)
        //    {
        //        return default;
        //    }
        //    return result.Content;
        //}

        ///// <summary>
        ///// 读取Int64
        ///// </summary>
        ///// <param name="address"></param>
        ///// <returns></returns>
        //public static long ReadInt641(string address)
        //{
        //    OperateResult<long> result = new OperateResult<long>();
        //    try
        //    {
        //        result = MelsecInstance1.ReadInt64(address);
        //    }
        //    catch (Exception ex)
        //    {
        //        logHelper.Error($"PLC读取Int16发生错误！address:[{address}]", ex);
        //        return default;
        //    }
        //    if (!result.IsSuccess)
        //    {
        //        return default;
        //    }
        //    return result.Content;
        //}

        ///// <summary>
        ///// 读取UInt64
        ///// </summary>
        ///// <param name="address"></param>
        ///// <returns></returns>
        //public static ulong ReadUInt641(string address)
        //{
        //    OperateResult<ulong> result = new OperateResult<ulong>();
        //    try
        //    {
        //        result = MelsecInstance1.ReadUInt64(address);
        //    }
        //    catch (Exception ex)
        //    {
        //        logHelper.Error($"PLC读取Int16发生错误！address:[{address}]", ex);
        //        return default;
        //    }
        //    if (!result.IsSuccess)
        //    {
        //        return default;
        //    }
        //    return result.Content;
        //}

        ///// <summary>
        ///// 读取Float
        ///// </summary>
        ///// <param name="address"></param>
        ///// <returns></returns>
        //public static float ReadFloat1(string address)
        //{
        //    OperateResult<float> result = new OperateResult<float>();
        //    try
        //    {
        //        result = MelsecInstance1.ReadFloat(address);
        //    }
        //    catch (Exception ex)
        //    {
        //        logHelper.Error($"PLC读取Float发生错误！address:[{address}]", ex);
        //        return default;
        //    }
        //    if (!result.IsSuccess)
        //    {
        //        return default;
        //    }
        //    return result.Content;
        //}

        ///// <summary>
        ///// 读取Double
        ///// </summary>
        ///// <param name="address"></param>
        ///// <returns></returns>
        //public static double ReadDouble1(string address)
        //{
        //    OperateResult<double> result = new OperateResult<double>();
        //    try
        //    {
        //        result = MelsecInstance1.ReadDouble(address);
        //    }
        //    catch (Exception ex)
        //    {
        //        logHelper.Error($"PLC读取Double发生错误！address:[{address}]", ex);
        //        return default;
        //    }
        //    if (!result.IsSuccess)
        //    {
        //        return default;
        //    }
        //    return result.Content;
        //}

        ///// <summary>
        ///// 字符串读取2
        ///// </summary>
        ///// <param name="address"></param>
        ///// <param name="length"></param>
        ///// <returns></returns>
        //public static string ReadString2(string address, ushort length)
        //{
        //    OperateResult<string> result = new OperateResult<string>();
        //    try
        //    {
        //        result = MelsecInstance2.ReadString(address, length);
        //    }
        //    catch (Exception ex)
        //    {
        //        logHelper.Error($"PLC2读取String发生错误！address:[{address}]", ex);
        //        return default;
        //    }
        //    if (!result.IsSuccess)
        //    {
        //        return default;
        //    }
        //    return result.Content;
        //}

        ///// <summary>
        ///// 读取bool
        ///// </summary>
        ///// <param name="address"></param>
        ///// <returns></returns>
        //public static bool ReadBool2(string address)
        //{
        //    OperateResult<bool> result = new OperateResult<bool>();
        //    try
        //    {
        //        result = MelsecInstance2.ReadBool(address);
        //    }
        //    catch (Exception ex)
        //    {
        //        logHelper.Error($"PLC读取Bool发生错误！address:[{address}]", ex);
        //        return default;
        //    }
        //    if (!result.IsSuccess)
        //    {
        //        return default;
        //    }
        //    return result.Content;
        //}

        ///// <summary>
        ///// 读取Int16
        ///// </summary>
        ///// <param name="address"></param>
        ///// <returns></returns>
        //public static short ReadInt162(string address)
        //{
        //    OperateResult<short> result = new OperateResult<short>();
        //    try
        //    {
        //        result = MelsecInstance2.ReadInt16(address);
        //    }
        //    catch (Exception ex)
        //    {
        //        logHelper.Error($"PLC读取Int16发生错误！address:[{address}]", ex);
        //        return default;
        //    }
        //    if (!result.IsSuccess)
        //    {
        //        return default;
        //    }
        //    return result.Content;
        //}

        ///// <summary>
        ///// 读取UInt16
        ///// </summary>
        ///// <param name="address"></param>
        ///// <returns></returns>
        //public static ushort ReadUInt162(string address)
        //{
        //    OperateResult<ushort> result = new OperateResult<ushort>();
        //    try
        //    {
        //        result = MelsecInstance2.ReadUInt16(address);
        //    }
        //    catch (Exception ex)
        //    {
        //        logHelper.Error($"PLC读取Int16发生错误！address:[{address}]", ex);
        //        return default;
        //    }
        //    if (!result.IsSuccess)
        //    {
        //        return default;
        //    }
        //    return result.Content;
        //}

        ///// <summary>
        ///// 读取Int32
        ///// </summary>
        ///// <param name="address"></param>
        ///// <returns></returns>
        //public static int ReadInt322(string address)
        //{
        //    OperateResult<int> result = new OperateResult<int>();
        //    try
        //    {
        //        result = MelsecInstance2.ReadInt32(address);
        //    }
        //    catch (Exception ex)
        //    {
        //        logHelper.Error($"PLC读取Int16发生错误！address:[{address}]", ex);
        //        return default;
        //    }
        //    if (!result.IsSuccess)
        //    {
        //        return default;
        //    }
        //    return result.Content;
        //}

        ///// <summary>
        ///// 读取UInt32
        ///// </summary>
        ///// <param name="address"></param>
        ///// <returns></returns>
        //public static uint ReadUInt322(string address)
        //{
        //    OperateResult<uint> result = new OperateResult<uint>();
        //    try
        //    {
        //        result = MelsecInstance2.ReadUInt32(address);
        //    }
        //    catch (Exception ex)
        //    {
        //        logHelper.Error($"PLC读取Int16发生错误！address:[{address}]", ex);
        //        return default;
        //    }
        //    if (!result.IsSuccess)
        //    {
        //        return default;
        //    }
        //    return result.Content;
        //}

        ///// <summary>
        ///// 读取Int64
        ///// </summary>
        ///// <param name="address"></param>
        ///// <returns></returns>
        //public static long ReadInt642(string address)
        //{
        //    OperateResult<long> result = new OperateResult<long>();
        //    try
        //    {
        //        result = MelsecInstance2.ReadInt64(address);
        //    }
        //    catch (Exception ex)
        //    {
        //        logHelper.Error($"PLC读取Int16发生错误！address:[{address}]", ex);
        //        return default;
        //    }
        //    if (!result.IsSuccess)
        //    {
        //        return default;
        //    }
        //    return result.Content;
        //}

        ///// <summary>
        ///// 读取UInt64
        ///// </summary>
        ///// <param name="address"></param>
        ///// <returns></returns>
        //public static ulong ReadUInt642(string address)
        //{
        //    OperateResult<ulong> result = new OperateResult<ulong>();
        //    try
        //    {
        //        result = MelsecInstance2.ReadUInt64(address);
        //    }
        //    catch (Exception ex)
        //    {
        //        logHelper.Error($"PLC读取Int16发生错误！address:[{address}]", ex);
        //        return default;
        //    }
        //    if (!result.IsSuccess)
        //    {
        //        return default;
        //    }
        //    return result.Content;
        //}

        ///// <summary>
        ///// 读取Float
        ///// </summary>
        ///// <param name="address"></param>
        ///// <returns></returns>
        //public static float ReadFloat2(string address)
        //{
        //    OperateResult<float> result = new OperateResult<float>();
        //    try
        //    {
        //        result = MelsecInstance2.ReadFloat(address);
        //    }
        //    catch (Exception ex)
        //    {
        //        logHelper.Error($"PLC读取Float发生错误！address:[{address}]", ex);
        //        return default;
        //    }
        //    if (!result.IsSuccess)
        //    {
        //        return default;
        //    }
        //    return result.Content;
        //}

        ///// <summary>
        ///// 读取Double
        ///// </summary>
        ///// <param name="address"></param>
        ///// <returns></returns>
        //public static double ReadDouble2(string address)
        //{
        //    OperateResult<double> result = new OperateResult<double>();

        //    try
        //    {
        //        result = MelsecInstance2.ReadDouble(address);
        //    }
        //    catch (Exception ex)
        //    {
        //        logHelper.Error($"PLC读取Double发生错误！address:[{address}]", ex);
        //        return default;
        //    }
        //    if (!result.IsSuccess)
        //    {
        //        return default;
        //    }
        //    return result.Content;
        //}
    }
}