using FreeRedis;
using System.Collections.Generic;
namespace Virtual_PLC
{
    /// 
    /// plc数据
    /// 
    public class PlcData
    {
        private static RedisClient Redis { get; set; }
        /// 
        /// 数据结构缓存
        /// 
        private static List PLCDatas { get; set; } = new List();
        /// 
        /// redis 链接字符串
        /// 
        /// Redis链接字符串
        public PlcData(string redisClient)
        {
            Redis = new RedisClient(redisClient);
        }
        /// 
        /// redis 链接字符串
        /// 
        /// 
        /// 
        public static PlcData Init(string redisClient)
        {
            return new PlcData(redisClient);
        }
        /// 
        /// 初始化PLC数据
        /// 
        /// 一个PLC
        public void InitPlcData(PLCData pLCData)
        {
            if (!PLCDatas.Contains(pLCData))
            {
                PLCDatas.Add(pLCData);
            }
            //用总长度除以数据长度,再以每断数据的起始位置、IP、DB组成Key
            var mun = pLCData.Length / pLCData.DataLength;
            int addstart = 0;
            for (int i = 0; i < mun; i++)
            {
                var key = $"{pLCData.IP}:{pLCData.DB}:{addstart}";
                if (Redis.Exists(key)) continue;
                Redis.Set(key, new byte[pLCData.DataLength]);
                addstart = addstart + pLCData.DataLength;
            }
        }
        /// 
        /// 初始化PLC数据
        /// 
        /// 多个PLC
        public void InitPlcData(List pLCDatas)
        {
            pLCDatas.ForEach(v =>
            {
                InitPlcData(v);
            });
        }
        /// 
        /// 按照DB读取
        /// 
        /// 
        /// 
        public static byte[] Read(PLCData pLCData)
        {
            byte[] data = new byte[pLCData.Length];
            //用总长度除以数据长度,再以每断数据的起始位置、IP、DB组成Key
            var mun = pLCData.Length / pLCData.DataLength;
            int addstart = 0;
            for (int i = 0; i < mun; i++)
            {
                var a = Redis.Get($"{pLCData.IP}:{pLCData.DB}:{addstart}");
                a.CopyTo(data, addstart);
                addstart = addstart + pLCData.DataLength;
            }
            return data;
        }
        /// 
        /// 按照长度读取
        /// 
        /// 
        /// 起始长度
        /// 
        public static byte[] Read(PLCData pLCData, int startLength)
        {
            return System.Text.Encoding.Default.GetBytes(Redis.Get($"{pLCData.IP}:{pLCData.DB}:{startLength}"));
        }
        /// 
        ///
        /// 
        public static void Write(PLCData pLCData, int startLength, byte[] value)
        {
            var data = PLCDatas.Find(v => v.IP == pLCData.IP && v.DB == pLCData.DB);
            var start = startLength < data.DataLength ? 0 : (data.DataLength - startLength) + startLength;
            //获取原有数据
            var bytes = System.Text.Encoding.Default.GetBytes(Redis.Get($"{pLCData.IP}:{pLCData.DB}:{start}"));
            value.CopyTo(bytes, startLength - 1);
            Redis.Set($"{pLCData.IP}:{pLCData.DB}:{start}", bytes);
        }
    }
    /// 
    /// PLC数据结构
    /// 
    public class PLCData
    {
        /// 
        /// IP
        /// 
        public string IP { get; set; }
        /// 
        /// DB
        /// 
        public int DB { get; set; }
        /// 
        /// 总长度
        /// 
        public int Length { get; set; }
        /// 
        /// 数据长度
        /// 
        public int DataLength { get; set; }
    }
}