using iCore.Rtdb;
using iCore.Rtdb.RtdbTable;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;

namespace Common
{
    public class MemoryTableDataSocket
    {
        private CoredbClient cln = null;

        //[Obsolete]
        public MemoryTableDataSocket(string sPoint)
        {   //""tarantool://guest@192.1.3.54:20"+计量点编号
            try
            {
                cln = new CoredbClient(AppConfigCache.icoredbTcp);// + sPoint.Substring(3, 2));//计量网
            }
            catch (Exception ex)
            {
                WriteLog("MemoryTableData:" + cln);
            }
        }

        public MemoryTableDataSocket(string sPoint, string serverUrl)
        {   //""tarantool://guest@192.1.3.54:20"+计量点编号
            try
            {
                cln = new CoredbClient(serverUrl);// + sPoint.Substring(3, 2));//计量网
            }
            catch (Exception ex)
            {
                WriteLog("MemoryTableData:" + cln);
            }
        }

        #region 监控界面使用

        /// <summary>
        /// 根据计量点取采集的值
        /// CAR11PlcStauts	PLC控制器状态	"0:初始值   数采服务器每隔2秒向PLC写入值1234；PLC会每隔2S不停用值4321覆盖"
        /// CAR11MesWeight 上位机仪表重量	129160
        /// HMI11LightWest HMI下发前红绿灯命令	"远控模式下：1、前红绿灯为绿灯；2、前红绿灯为红灯；"
        /// CAR11LightWest 前红绿灯	"1、前红绿灯为绿灯；2、前红绿灯为红灯；"
        /// CAR11LightEast 后红绿灯	"1、前红绿灯为绿灯；2、前红绿灯为红灯；"
        /// HMI11CaptureWest HMI控制前抓拍触发信号	"0、不操作；1、HMI下发西边抓拍单元抓拍信号；"
        /// HMI11CaptureEast HMI控制后抓拍触发信号	"0、不操作；1、HMI下发东边抓拍单元抓拍信号；"
        /// HMI11ClearZero HMI下发仪表清零指令	1：HMI对仪表清零
        /// CAR11StaticStatus   车辆检测	"0、东西方向激光均无报警； 1、过磅时，西边激光报警；2、过磅时，东边激光报警；3、过磅时，东西两边激光均报警"
        /// CAR11InfraredWest 前车量检测状态	"1、前激光报警；2、前激光无报警；"
        /// CAR11InfraredEast 后车量检测状态	"1、后激光报警；2、后激光无报警；"
        /// CAR11ZeroWeightStatus 汽车空磅状态	0、其它，1、零点报警，红绿灯变红，
        /// HMI11SwitchLight 红绿灯远控/自动	"1、远方切换开关处于自动控制位置；2、远方切换开关处于远方控制位置；远方切换方开关位于界面上"
        /// CAR11SwitchLight PLC红绿灯控制模式状态	"PLC有三种控制模式：1、自动、2、远控；3、检修。 优先权从高到低：检修>远控>自动。PLC默认为自动控制，设2个切换开关，2个在远方操作人员在界面上，可完成远控/自动切换。一个开关在现场PLC控制箱中，可完成检修/自动切换。"
        /// CAR11VlDirection 左红外光栅检测	1、光栅报警；2、光栅无报警
        /// CAR11VlPLCWeight    右红外光栅检测	1、光栅报警；2、光栅无报警
        /// </summary>
        public List<LiveData> getWarnInfo(string sPoint)
        {
            try
            {
                List<LiveData> ltn = (List<LiveData>)cln.CallRpc<LiveData>("LiveData:readByPointId", new object[] { sPoint });
                return ltn;
            }
            catch (Exception ex)
            {
                WriteLog("读采集数据异常错误：" + ex.Message);
                return null;
            }
        }
        /// <summary>
        /// 写入控制表（道闸，仪表，红外,LED等）
        /// </summary>
        /// <param name="sPoint">计量点</param>
        /// <param name="OptionType">操作类型</param>
        /// <param name="value">被写入的信息</param>
        /// <param name="strUserID">用户编号</param>
        /// <param name="errorInfo">异常信息接收</param>
        /// <returns></returns>
        public bool writeWarnInfo(string sPoint, string OptionType, string value, string strUserID, out string errorInfo)
        {
            try
            {
                string strPntid = sPoint.Replace("CAR", "HMI") + OptionType;
                cln.CallRpc<int>("Control:doCommand", new object[] { strPntid, value, strUserID });
                errorInfo = "";
                return true;
            }
            catch (Exception ex)
            {
                WriteLog("写入信息到内存表异常！" + ex.Message);
                errorInfo = "写入信息到内存表异常！" + ex.Message;
                return false;
            }
        }

        #endregion 监控界面使用

        #region 计量主程序使用

        /// <summary>
        /// 读取Live表 某个字段信息
        /// </summary>
        /// <param name="value"></param>
        /// <param name="PointIdKey">CAR11</param>
        /// <param name="TagName">PowerStatus</param>
        /// <returns>JArray  arr[0].Tagname, arr[0].Value, arr[0].DateTime, arr[0].Source</returns>
        public JArray LiveTable(string PointIdKey, string TagName)
        {
            try
            {
                List<Live> arr = (List<Live>)cln.CallRpc<Live>("Live.Table:select", new object[] { PointIdKey + TagName });//读
                if (arr != null && arr.Count > 0)
                {
                    JArray jArray = new JArray(arr[0].Tagname, arr[0].Value, arr[0].DateTime, arr[0].Source);
                    return jArray;
                }
                return null;
            }
            catch (Exception exp)
            {
                WriteLog("LiveTable:" + exp.Message + exp.StackTrace);
                return null;
            }
        }

        /// <summary>
        /// 读取实时表，一个计量点只有一条数据（重量，稳定，红外，车号等信息）
        /// </summary>
        /// <param name="value"></param>
        /// <param name="PointIdKey">计量点编号</param>
        /// <returns>
        ///     MemoryTableDataSocket MemoClass = new MemoryTableDataSocket(strPntNo);
        ///     JArray aryValue = MemoClass.TrackTable(strPntNo);//Track表数据每个计量点的数据
        ///     string pointId = aryValue[0]; string carNo = aryValue[1];
        ///     对照如下：
        ///     0	pointid	计量点	string	CAR11,CAR12,CAR13等计量点编号
        ///     1	status 车辆状态    number	0:等待车辆 1:车辆上称 2:重量不稳定  3:重量稳定  4:计量完成  5:下称
        ///     2	carno 车号  string 鄂B23955
        ///     3	weight 重量  number
        ///     4	weightStatus 重量状态    number	0:重量稳定; 1:重量不稳定;  2:空磅
        ///     5	parkStatus 停车状态    number	0:正常(头尾都未压线)  1:车头压线  2：车尾压线  3:两头压线; 记录在重量稳定后生成
        ///     6	datetime 上称时间    uint 当前时间的距离1970.1.1.08:00时间的秒数; 秒
        ///     7	LicType 车牌类型    number	0:车牌抓拍； 1:RFID 识别
        ///     8	WeightSave 计量保存重量  uint
        ///     9	FinishTime 过磅完成时间  uint 秒
        ///     10	entry 入口  string East = 东边, West = 西边
        ///     11	exit 出口  string East = 东边, West = 西边
        ///     12	platenoList 抓拍车牌信息  array	"{direct, plateno} direct:string 方向 plateno: string 车牌/电子车牌"
        ///     13	rfidList RFID识别车牌信息  array	"{direct, plateno} direct:string 方向plateno: string 车牌/电子车牌"
        /// </returns>
        public JArray TrackTable(string PointIdKey)
        {
            try
            {
                List<Track> arr = (List<Track>)cln.CallRpc<Track>("Track.Table:select", new object[] { PointIdKey });//读
                if (arr != null && arr.Count > 0)
                {
                    List<CarInfo> PlateNoList = arr[0].PlateNoList == null ? new List<CarInfo>() : arr[0].PlateNoList;
                    List<CarInfo> RfidList = arr[0].RfidList == null ? new List<CarInfo>() : arr[0].RfidList;

                    //静态衡
                    Dictionary<string, double> WgtList = arr[0].WeightList == null ? new Dictionary<string, double>() : arr[0].WeightList;

                    JArray jArray = new JArray(
                        arr[0].Pointid, //0
                        arr[0].Status,  //1
                        arr[0].CarNo, //2
                        arr[0].Weight, //3
                        arr[0].WeightStatus, //4
                        arr[0].StopStatus, //5
                        arr[0].Datetime, //6
                        arr[0].LicType, //7
                        PlateNoList.Count == 0 ? "" : PlateNoList[PlateNoList.Count - 1].CarNo, //8
                        RfidList.Count == 0 ? "" : RfidList[RfidList.Count - 1].CarNo, //9
                        arr[0].WeightSave, //10
                        arr[0].FinishTime, //11
                        arr[0].Entry, //12
                        arr[0].Exit); //13

                    double mainWgt = 0;
                    double viceWgt = 0;

                    if (WgtList.Count > 1)
                    {
                        foreach (var it in WgtList)
                        {
                            if (it.Key.EndsWith("WeightMain"))
                            {
                                //jArray.Add(it.Value); //14
                                mainWgt = it.Value;
                            }
                            else if (it.Key.EndsWith("WeightVice"))
                            {
                                //jArray.Add(it.Value); //15
                                viceWgt = it.Value;
                            }
                        }
                        jArray.Add(mainWgt); //14
                        jArray.Add(viceWgt); //15
                    }
                    else
                    {
                        jArray.Add(arr[0].Weight);
                    }
                    try
                    {
                        WriteLog(PointIdKey + "重量采集:" + "计量点：" + arr[0].Pointid + "车号：" + arr[0].CarNo + "重量状态（0:重量稳定; 1:重量不稳定;  2:空磅）：" + arr[0].WeightStatus + "重量" + arr[0].Weight);
                    }
                    catch (Exception)
                    {
                        WriteLog(PointIdKey + "写日志异常");
                    }
                    return jArray;
                }

                WriteLog(PointIdKey + "空值");
                return null;
            }
            catch (Exception exp)
            {
                try
                {
                    cln = new CoredbClient(AppConfigCache.icoredbTcp);
                }
                catch { }

                WriteLog(PointIdKey + "_TrackTable:" + exp.Message + exp.StackTrace + "空值");
                return null;
            }
        }

        #endregion 计量主程序使用

        public List<JArray> TrackTable(params string[] PointIdKeys)
        {
            try
            {
                List<Track> arr = (List<Track>)cln.CallRpc<Track>("Track.Table:select", new object[] { });//读
                if (arr != null && arr.Count > 0)
                {
                    List<JArray> lj = new List<JArray>();
                    foreach (Track tk in arr)
                    {
                        foreach (string strPointKey in PointIdKeys)
                        {
                            if (tk.Pointid == strPointKey)
                            {
                                //静态衡
                                Dictionary<string, double> WgtList = tk.WeightList == null ? new Dictionary<string, double>() : tk.WeightList;

                                JArray jArray = new JArray(
                                    tk.Pointid, //0 pointid	计量点	string	CAR11,CAR12,CAR13等计量点编号
                                    tk.Weight, //1 重量  number
                                    tk.WeightStatus, //2  重量状态    number	0:重量稳定; 1:重量不稳定;  2:空磅
                                    tk.Datetime //3 上称时间    uint 当前时间的距离1970.1.1.08:00时间的秒数; 秒
                                 );

                                double mainWgt = 0;
                                double viceWgt = 0;

                                if (WgtList.Count > 1)
                                {
                                    foreach (var it in WgtList)
                                    {
                                        if (it.Key.EndsWith("WeightMain"))
                                        {
                                            mainWgt = it.Value;
                                        }
                                        else if (it.Key.EndsWith("WeightVice"))
                                        {
                                            viceWgt = it.Value;
                                        }
                                    }
                                    jArray.Add(mainWgt); //4
                                    jArray.Add(viceWgt); //5
                                }
                                else
                                {
                                    jArray.Add(tk.Weight);
                                }
                                lj.Add(jArray);
                            }
                        }
                    }
                    return lj.Count > 0 ? lj : null;
                }
                WriteLog(string.Format("计量点[{0}]没有对应的采集信息:", string.Join("", PointIdKeys)));
                return null;
            }
            catch (Exception exp)
            {
                try
                {
                    cln = new CoredbClient(AppConfigCache.icoredbTcp);
                }
                catch { }
                WriteLog("調用TrackTable异常:" + exp.Message + exp.StackTrace + "空值");
                return null;
            }
        }

        /// <summary>
        /// 查询List的数据
        /// </summary>
        /// <param name="PointIdKeys"></param>
        /// <returns></returns>
        public List<JArray> TrackTableList(params string[] PointIdKeys)
        {
            try
            {
                List<Track> arr = (List<Track>)cln.CallRpc<Track>("Track.Table:select", new object[] { });//读
                if (arr != null && arr.Count > 0)
                {
                    List<JArray> lj = new List<JArray>();
                    foreach (Track tk in arr)
                    {
                        foreach (string strPointKey in PointIdKeys)
                        {
                            if (tk.Pointid == strPointKey)
                            {
                                List<CarInfo> PlateNoList = tk.PlateNoList == null ? new List<CarInfo>() : tk.PlateNoList;
                                List<CarInfo> RfidList = tk.RfidList == null ? new List<CarInfo>() : tk.RfidList;
                                JArray jArray = new JArray(
                                    tk.Pointid, //0
                                    tk.Status,  //1
                                    tk.CarNo, //2
                                    tk.Weight, //3
                                    tk.WeightStatus, //4
                                    tk.StopStatus, //5
                                    tk.Datetime, //6
                                    tk.LicType, //7
                                    PlateNoList.Count == 0 ? "" : PlateNoList[PlateNoList.Count - 1].CarNo, //8
                                    RfidList.Count == 0 ? "" : RfidList[RfidList.Count - 1].CarNo, //9
                                    tk.WeightSave, //10
                                    tk.FinishTime, //11
                                    tk.Entry, //12
                                    tk.Exit); //13
                                try
                                {
                                    switch (strPointKey.ToUpper())
                                    {
                                        case "CAR40":
                                            WriteLogSwicth("优钢热送", strPointKey + "优钢热送:" + "计量点：" + tk.Pointid + "；重量状态(0:重量稳定; 1:重量不稳定;  2:空磅)：" + tk.WeightStatus + " ；重量" + tk.Weight);
                                            break;
                                        case "CAR41":
                                            WriteLogSwicth("高棒热送", strPointKey + "高棒热送:" + "计量点：" + tk.Pointid + "；重量状态(0:重量稳定; 1:重量不稳定;  2:空磅)：" + tk.WeightStatus + " ；重量" + tk.Weight);
                                            break;
                                        case "CAR42":
                                            WriteLogSwicth("普棒热送", strPointKey + "普棒热送:" + "计量点：" + tk.Pointid + "；重量状态(0:重量稳定; 1:重量不稳定;  2:空磅)：" + tk.WeightStatus + " ；重量" + tk.Weight);
                                            break;
                                        case "CAR43":
                                            WriteLogSwicth("板材热送", strPointKey + "板材热送:" + "计量点：" + tk.Pointid + "；重量状态(0:重量稳定; 1:重量不稳定;  2:空磅)：" + tk.WeightStatus + " ；重量" + tk.Weight);
                                            break;
                                        case "CAR44":
                                            WriteLogSwicth("高线热送", strPointKey + "高线热送:" + "计量点：" + tk.Pointid + "；重量状态(0:重量稳定; 1:重量不稳定;  2:空磅)：" + tk.WeightStatus + " ；重量" + tk.Weight);
                                            break;
                                        default:
                                            break;
                                    }
                                }
                                catch (Exception)
                                {
                                    WriteLog(strPointKey + "写日志异常");
                                }
                                lj.Add(jArray);
                            }
                        }
                    }
                    return lj.Count > 0 ? lj : null;
                }
                WriteLog(string.Format("计量点[{0}]没有对应的采集信息:", string.Join("", PointIdKeys)));
                return null;
            }
            catch (Exception exp)
            {
                try
                {
                    cln = new CoredbClient(AppConfigCache.icoredbTcp);
                }
                catch { }
                WriteLog("調用TrackTable异常:" + exp.Message + exp.StackTrace + "空值");
                return null;
            }
        }

        /// <summary>
        /// 按照计量点的输出日志
        /// </summary>
        /// <param name="strPointName"></param>
        /// <param name="str"></param>
        private void WriteLogSwicth(string strPointName, string str)
        {
            try
            {
                string m_szRunPath;
                m_szRunPath = PbCache.path;
                if (Directory.Exists(m_szRunPath + "\\log") == false)
                {
                    Directory.CreateDirectory(m_szRunPath + "\\log");
                }
                string strDate = DateTime.Now.ToString("yyyyMMdd");
                string strPathFile = m_szRunPath + "\\log\\" + strDate;
                if (!Directory.Exists(strPathFile))//如果不存在就创建file文件夹
                {
                    Directory.CreateDirectory(strPathFile);
                }
                TextWriter tw = new StreamWriter(strPathFile + "\\重量采集日志_" + strPointName + strDate + ".log", true);

                tw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                tw.WriteLine(str);
                tw.WriteLine("\r\n");

                tw.Close();
            }
            catch { }
        }

        private void WriteLog(string str)
        {
            try
            {
                string m_szRunPath;
                m_szRunPath = PbCache.path;
                if (Directory.Exists(m_szRunPath + "\\log") == false)
                {
                    Directory.CreateDirectory(m_szRunPath + "\\log");
                }
                string strDate = DateTime.Now.ToString("yyyyMMdd");
                string strPathFile = m_szRunPath + "\\log\\" + strDate;
                if (!Directory.Exists(strPathFile))//如果不存在就创建file文件夹
                {
                    Directory.CreateDirectory(strPathFile);
                }
                TextWriter tw = new StreamWriter(strPathFile + "\\重量采集日志_" + strDate + ".log", true);

                tw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                tw.WriteLine(str);
                tw.WriteLine("\r\n");

                tw.Close();
            }
            catch { }
        }
    }
}