using Microsoft.Extensions.Logging;
using SlnMesnac.Config;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using SlnMesnac.Plc.Factory;

#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
* 版权所有 (c) 2024 WenJY 保留所有权利。
* CLR版本：4.0.30319.42000
* 机器名称：LAPTOP-E0N2L34V
* 命名空间：SlnMesnac.Plc
* 唯一标识：496f8d2b-70e3-4a05-ae18-a9b0fcd06b82
*
* 创建者：WenJY
* 电子邮箱：wenjy@mesnac.com
* 创建时间：2024-03-27 21:58:35
* 版本：V1.0.0
* 描述：
*
*--------------------------------------------------------------------
* 修改人：
* 时间：
* 修改说明：
*
* 版本：V1.0.0
*--------------------------------------------------------------------*/
#endregion << 版 本 注 释 >>
namespace SlnMesnac.Plc
{
    /// <summary>
    /// PLC连接池
    /// </summary>
    public class PlcPool
    {
        private ILogger<PlcPool> _logger;
        private readonly AppConfig _appConfig;

        private Dictionary<string, PlcAbsractFactory> keyValuePairs ;

        private readonly InovanceFactory _inovance;
        private readonly MelsecBinaryFactory _melsecBinary;
        private readonly OmronNJFactory _omronNj;
        private readonly SiemensFactory _siemens;

        public PlcPool(ILogger<PlcPool> logger, InovanceFactory inovance,MelsecBinaryFactory melsecBinary,OmronNJFactory omronNj,SiemensFactory siemens, AppConfig appConfig)
        {
            _logger = logger;
            _inovance = inovance;
            _melsecBinary = melsecBinary;
            _omronNj = omronNj;
            _siemens = siemens;
            _appConfig = appConfig;

            keyValuePairs = new Dictionary<string, PlcAbsractFactory>();
        }
        public void Init()
        {
            if (!HslCommunication.Authorization.SetAuthorizationCode("1839541f-8fb4-42c4-a13f-733b027fe5af"))
            {
                _logger.LogInformation("HslCommunication激活失败，可用时长24小时");
            }
            _logger.LogInformation("HslCommunication 11.8.1.0激活成功");

            if (_appConfig.plcConfig != null)
            {
                foreach (var item in _appConfig.plcConfig)
                {
                    if (item.isFlage)
                    {
                        AddPlc(item.plcType, item.plcIp, item.plcPort, item.plcKey);
                    }
                }
            }
            else
            {
                _logger.LogInformation("PLC配置信息为空");
            }
        }

        /// <summary>
        /// 添加PLC连接
        /// </summary>
        /// <param name="plcType"></param>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <param name="key"></param>
        public void AddPlc(string plcType, string ip, int port, string key)
        {
            try
            {
                PlcAbsractFactory _plc = null;
                switch (plcType)
                {
                    case "InovancePlc":
                        _plc = _inovance;
                        break;
                    case "MelsecBinaryPlc":
                        _plc = _melsecBinary;
                        break;
                    case "OmronNJPlc":
                        _plc = _omronNj;
                        break;
                    case "SiemensPlc":
                        _plc = _siemens;
                        break;
                    default:
                        break;
                }
                var connectResult = _plc.Connect(ip, port);
                if (connectResult)
                {
                    _logger.LogInformation($"PLC：{ip}:{port};连接成功，时间：{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
                    if (!keyValuePairs.ContainsKey(key))
                    {
                        keyValuePairs.Add(key, _plc);
                    }
                    else
                    {
                        keyValuePairs[key] = _plc;
                    }
                }
                else
                {
                    _logger.LogInformation($"PLC：{ip}:{port};连接失败，时间：{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
                }
            }
            catch (Exception e)
            {
                _logger.LogError($"PLC初始化连接异常：{e.Message}");
            }
        }

        /// <summary>
        /// 获取PLC
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public PlcAbsractFactory GetPlcByKey(string key)
        {
            try
            {
                return keyValuePairs[key];
            }
            catch (Exception e)
            {
                throw new ArgumentException($"根据PLC Key获取连接信息异常:{e.Message}"); ;
            }
        }

        /// <summary>
        /// 获取所有PLC信息
        /// </summary>
        /// <returns></returns>
        public Dictionary<string, PlcAbsractFactory> GetAll()
        {
            return keyValuePairs;
        }

        /// <summary>
        /// 关闭所有连接
        /// </summary>
        /// <returns></returns>
        public bool disConnectAll()
        {
            bool result = false;
            try
            {
                foreach (var kv in keyValuePairs)
                {
                    if (kv.Value != null)
                    {
                        kv.Value.DisConnect();
                    }
                }
                result = true;
            }
            catch (Exception ex)
            {
                _logger.LogError("关闭PLC连接异常", ex);
            }

            return result;
        }
    }
}
