using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using MECF.Framework.RT.Core.IoProviders.Siemens.IMessage;
using MECF.Framework.RT.Core.IoProviders.Siemens.Net.NetworkBase;
using MECF.Framework.RT.Core.IoProviders.Siemens.Transfer;
namespace MECF.Framework.RT.Core.IoProviders.Siemens
{    /// 
     /// 一个西门子的客户端类,使用S7协议来进行数据交互 ->
     /// A Siemens client class that uses the S7 protocol for data interaction
     /// 
     /// 
     /// 地址支持的列表如下:
     /// 
     ///   
     ///     地址名称
     ///     地址代号
     ///     示例
     ///     地址进制
     ///     字操作
     ///     位操作
     ///     备注
     ///   
     ///   - 
     ///     中间寄存器
     ///     M
     ///     M100,M200
     ///     10
     ///     √
     ///     √
     ///     
     ///   ///
- 
     ///     输入寄存器
     ///     I
     ///     I100,I200
     ///     10
     ///     √
     ///     √
     ///     
     ///   ///
- 
     ///     输出寄存器
     ///     Q
     ///     Q100,Q200
     ///     10
     ///     √
     ///     √
     ///     
     ///   ///
- 
     ///     DB块寄存器
     ///     DB
     ///     DB1.100,DB1.200
     ///     10
     ///     √
     ///     √
     ///     
     ///   ///
- 
     ///     V寄存器
     ///     V
     ///     V100,V200
     ///     10
     ///     √
     ///     √
     ///     V寄存器本质就是DB块1
     ///   ///
- 
     ///     定时器的值
     ///     T
     ///     T100,T200
     ///     10
     ///     √
     ///     √
     ///     未测试通过
     ///   ///
- 
     ///     计数器的值
     ///     C
     ///     C100,C200
     ///     10
     ///     √
     ///     √
     ///     未测试通过
     ///   ///
/// 对于200smartPLC的V区,就是DB1.X,例如,V100=DB1.100
     /// 
     /// 
     ///
        /// Get or set the current PLC connection mode, PG: 0x01, OP: 0x02, S7Basic: 0x03...0x10
        /// 
        public byte ConnectionType
        {
            get => this.plcHead1[20];
            set
            {
                if (CurrentPlc == SiemensPLCS.S200 ||
                    CurrentPlc == SiemensPLCS.S200Smart)
                {
                }
                else
                {
                    this.plcHead1[20] = value;
                }
            }
        }
        /// 
        /// 西门子相关的本地TSAP参数信息
        /// A parameter information related to Siemens
        /// 
        public int LocalTSAP
        {
            get => this.plcHead1[16] * 256 + this.plcHead1[17];
            set
            {
                if (CurrentPlc == SiemensPLCS.S200 ||
                    CurrentPlc == SiemensPLCS.S200Smart)
                {
                }
                else
                {
                    this.plcHead1[16] = BitConverter.GetBytes(value)[1];
                    this.plcHead1[17] = BitConverter.GetBytes(value)[0];
                }
            }
        }
        #endregion
        #region NetworkDoubleBase Override
        /// 
        /// 连接上服务器后需要进行的二次握手操作 -> Two handshake actions required after connecting to the server
        /// 
        /// 网络套接字 -> Network sockets
        /// 是否初始化成功,依据具体的协议进行重写 ->
        /// Whether the initialization succeeds and is rewritten according to the specific protocol
        protected override OperateResult InitializationOnConnect(Socket socket)
        {
            // 第一次握手 -> First handshake
            OperateResult read_first = ReadFromCoreServer(socket, plcHead1);
            if (!read_first.IsSuccess) return read_first;
            // 第二次握手 -> Second handshake
            OperateResult read_second = ReadFromCoreServer(socket, plcHead2);
            if (!read_second.IsSuccess) return read_second;
            // 返回成功的信号 -> Return a successful signal
            return OperateResult.CreateSuccessResult();
        }
        #endregion
        #region Read OrderNumber
        /// 
        /// 从PLC读取订货号信息 -> Reading order number information from PLC
        /// 
        /// CPU的订货号信息 -> Order number information for the CPU
        public OperateResult ReadOrderNumber()
        {
            OperateResult read = ReadFromCoreServer(plcOrderNumber);
            if (!read.IsSuccess) return OperateResult.CreateFailedResult(read);
            return OperateResult.CreateSuccessResult(Encoding.ASCII.GetString(read.Content, 71, 20));
        }
        #endregion
        #region Start Stop
        /// 
        /// 对PLC进行热启动
        /// 
        /// 是否启动成功的结果对象
        public OperateResult HotStart()
        {
            OperateResult read = ReadFromCoreServer(S7_HOT_START);
            if (!read.IsSuccess) return read;
            if (read.Content.Length < 19) return new OperateResult("Receive error");
            if (read.Content[19] != pduStart) return new OperateResult("Can not start PLC");
            else if (read.Content[20] != pduAlreadyStarted) return new OperateResult("Can not start PLC");
            return OperateResult.CreateSuccessResult();
        }
        /// 
        /// 对PLC进行冷启动
        /// 
        /// 是否启动成功的结果对象
        public OperateResult ColdStart()
        {
            OperateResult read = ReadFromCoreServer(S7_COLD_START);
            if (!read.IsSuccess) return read;
            if (read.Content.Length < 19) return new OperateResult("Receive error");
            if (read.Content[19] != pduStart) return new OperateResult("Can not start PLC");
            else if (read.Content[20] != pduAlreadyStarted) return new OperateResult("Can not start PLC");
            return OperateResult.CreateSuccessResult();
        }
        /// 
        /// 对PLC进行停止
        /// 
        /// 是否启动成功的结果对象
        public OperateResult Stop()
        {
            OperateResult read = ReadFromCoreServer(S7_STOP);
            if (!read.IsSuccess) return read;
            if (read.Content.Length < 19) return new OperateResult("Receive error");
            if (read.Content[19] != pduStop) return new OperateResult("Can not stop PLC");
            else if (read.Content[20] != pduAlreadyStopped) return new OperateResult("Can not stop PLC");
            return OperateResult.CreateSuccessResult();
        }
        #endregion
        #region Read Support
        /// 
        /// 从PLC读取数据,地址格式为I100,Q100,DB20.100,M100,T100,C100以字节为单位 ->
        /// Read data from PLC, address format I100,Q100,DB20.100,M100,T100,C100 in bytes
        /// 
        /// 起始地址,格式为I100,M100,Q100,DB20.100 ->
        /// Starting address, formatted as I100,M100,Q100,DB20.100
        /// 读取的数量,以字节为单位 -> The number of reads, in bytes
        /// 是否读取成功的结果对象 -> Whether to read the successful result object
        /// 
        /// 对于200smartPLC的V区,就是DB1.X,例如,V100=DB1.100
        /// 
        /// 
        /// 假设起始地址为M100,M100存储了温度,100.6℃值为1006,M102存储了压力,1.23Mpa值为123,M104,M105,M106,M107存储了产量计数,读取如下:
        ///