using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
using cn.edu.suda.sumcu.iot.json;
using cn.edu.suda.sumcu.iot.util;
using System.Data;
using cn.edu.suda.sumcu.iot.wsServices;
using cn.edu.suda.sumcu.iot.form;
using cn.edu.suda.sumcu.iot.data;
using System.Net.Mail;
using System.Net;
using System.Xml;
using System.IO;



namespace cn.edu.suda.sumcu.iot.state
{

    class myState
    {

        public String gatewayaddr, gatewayhardaddr, datetime; //硬件地址、硬件过滤地址、日期
        public static string lastsendmailtime = "";//全局变量，存放最后一次发送邮件时间
        private static string lastsendphonetime = "";//全局变量，存放最后一次发送短信时间
        public static string phoneflag = "OFF";//全局变量，设置短信发送开关
        public static float mailinterval = 1.0f;//全局变量，存放邮件发送间隔

        //
        String[] NodeCharType = { "", "", "", "", "", "", "", "", "", ""};
        String[] NodeState = { "", "", "", "", "", "", "", "", "", "" };
        string[] NumType = { "71", "80", "84", "86" };//存放节点类型的数值
        string[] CharType = { "Infrared-Temp", "PH-Sensor", "Contact-Temp", "Voltage" };//存放节点类型的数值随对应文本

        //获取json中关于节点的数据，上限，下限，判断状态后插入数据库中，并且更新saferunning time,然后每隔一小时发邮件
        [Obsolete]
        public void Deealjson(FrameData data)
        {
            var warningjson = new StringBuilder();
            bool flag = false;
            SQLCommand mysql = new SQLCommand(System.Configuration.//创建一个数据库的连接对象
            ConfigurationManager.AppSettings["connectionString"], "State");
            // mysql.szh_createtable();//创建表
            //判断是否存在今日的数据
            string  sqlstr = "", restr = "";//临时存放sql语句，临时存放返回客户端消息
            var jstemp = new StringBuilder();
            DataTable iotime = mysql.szh_selectmaxdate();
            //为类赋值
            this.datetime = DateTime.Now.ToString("yyyyMMdd");
            this.gatewayaddr = data.Parameter[23].value.ToString();
            this.gatewayhardaddr = data.Parameter[26].value.ToString();
                                             
            //把节点类型由数字换成文字
            for (int i = 0; i < 10; i++)
            {
                for (int t = 0; t < 4; t++)
                {
                    //找一个数字类型换成文字类型
                    if (data.Parameter[i*8+27].value.Trim() == NumType[t])
                    {
                        this.NodeCharType[i] = CharType[t];
                    }
                }
            }
                                
            
            //根据数据判断,得出节点状态，0：不存在，1：离线，2：正常，3：不正常
            for (int i = 0; i < 10; i++)
            {
                int xh = i*8 + 30;
                double sj = double.Parse(data.Parameter[xh].value);
                double up = double.Parse(data.Parameter[xh+1].value);
                double low = double.Parse(data.Parameter[xh+2].value);
                NodeState[i] = "1";//默认为节点不存在
                if (sj <= 0.01)     //节点不存在
                {
                    NodeState[i] = "0";
                }
                else if ((sj >= low) && (sj <= up))
                {
                    NodeState[i] = "2";//节点数据正常
                }
                else
                {
                    NodeState[i] = "3";//节点数据异常
                }
            }

            string mytemp = DateTime.Now.ToString("HHmmss");    //系统时间

            //获取当前的对应硬件过滤地址和时间的Datatable对象
            sqlstr = "select * from State where gatewayhardaddr = '" + this.gatewayhardaddr +
                "' and iotime = '" + this.datetime + "'";
            DataTable mydt = mysql.ExecuteQueryReturnDT(sqlstr);
            //如果时间相同且硬件过滤地址相同执行更新操作
            if (mydt.Rows.Count != 0)
            {
                sqlstr = "UPDATE State SET gatewayaddr = '" + this.gatewayaddr + "',";//sql更新语句定位
                sqlstr += "gatewayhardaddr='" + this.gatewayhardaddr + "',";
                for (int i = 0; i < 10; i++)//循环添入节点状态值
                {
                    //节点一天内曾上传过数据，但之后数据不存在，设为节点离线
                    if (mydt.Rows[0][i + 2].ToString() != "0" && NodeState[i] == "0")
                    {
                        NodeState[i] = "1";
                    }
                    //将更新后的节点状态写入数据库
                    if(i<9)  sqlstr += "node" + (i + 1).ToString() + "='" + NodeState[i] + "',";
                    else sqlstr += "node" + (i + 1).ToString() + "='" + NodeState[i] + "'";
                }
                sqlstr += " WHERE gatewayhardaddr = " + this.gatewayhardaddr;
                sqlstr += " and iotime = " + this.datetime;
            }
            else   //不同则执行插入操作
            {
                sqlstr = "INSERT INTO State (gatewayaddr, gatewayhardaddr,iotime,"+
                    "node1,node2,node3,node4,node5,node6,node7,node8,node9,node10) VALUES (";//sql更新语句定位
                sqlstr += "'" + this.gatewayaddr + "',";
                sqlstr += "'" + this.gatewayhardaddr + "',";
                sqlstr += "'" + this.datetime + "',";
                for (int i = 0; i < 10; i++)// //将每日第一次节点状态写入数据库
                {
                    if(i<9)  sqlstr += "'" + NodeState[i] + "',";
                    else sqlstr += "'" + NodeState[i] + "'";
                }
                sqlstr += ")";
            }
            mysql.ExecuteNonQuery(sqlstr);    //执行sql语句



            //循环检查报警信息
            for (int i = 0; i < 10; i++)
            {
                //如果节点状态为不正常，触发报警，0：不存在，1：离线，2：正常，3：不正常
                if (NodeState[i] == "3")
                {
                    int xh = i * 8 + 30;
                    string sj = data.Parameter[xh].value;//节点数据
                    string up = data.Parameter[xh + 1].value;//节点上限
                    string low = data.Parameter[xh + 2].value;//节点下限
                    warningjson.Append("Node:Node"+(i+1).ToString()+"<br>NodeType:" + this.NodeCharType[i] + "<br>Current Data:" +
                           sj + "<br>Max Data:" + up + "<br>Min Data:" + low + "<br>");
                    flag = true;
                }
            }
            FrmMain.myhardaddr = this.gatewayhardaddr;//把现在的硬件过滤地址放到FrmMain中

            //如果状态有红字就发送邮件给数据库里所有人
            if (flag)
            {
                flag = false;
                //获取报警节点的信息
                //Phone配置
                string phonesql = "select * from Phone";
                SQLCommand sqlphonetemp = new SQLCommand(System.Configuration.ConfigurationManager.AppSettings["connectionString"], "Phone");
                DataTable phonedt = sqlphonetemp.ExecuteQueryReturnDT(phonesql);
                StringBuilder MyStringBuilder = new StringBuilder();
                //循环添加要发送的人电话号码
                for (int i = 0; i < phonedt.Rows.Count; i++)
                {
                    if (i == phonedt.Rows.Count - 1)
                    {
                        MyStringBuilder.Append(phonedt.Rows[i][0].ToString());
                        break;
                    }
                    MyStringBuilder.Append(phonedt.Rows[i][0].ToString() + ",");

                }
                string telephone = MyStringBuilder.ToString();

                //【200509】Mail配置
                System.Web.Mail.MailMessage mail = new System.Web.Mail.MailMessage();
                mail.Subject = "Node Warning"; //邮件主题
                mail.BodyFormat = System.Web.Mail.MailFormat.Html;//邮件发送的格式为HTML
                mail.Body = "<b>" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "</b> <br>The Lastest warning Node:Gateway" + 
                    this.gatewayhardaddr + "<br>" + "Floor:" + this.gatewayaddr + "<br>" + warningjson + 
                    "<br>Warnings Info:<br>" + getmailinformation()+ "【TE Warning】";//邮件正文  
                mail.BodyEncoding = Encoding.UTF8;//正文编码
                mail.Priority = System.Web.Mail.MailPriority.Normal;//优先级
                mail.From = ("EHS_alarm@te.com");//发件者邮箱地址
                mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", "0");//身份验证  
                //mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendusername", "EHS_alarm@te.com");//用户名
                //mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendpassword", "TEEHS001");//授权码或者企业的密码
                mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpserverport", "25");//端口，但邮件默认端口是25，可以尝试465
                mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpusessl", "false");//是否ssl
                System.Web.Mail.SmtpMail.SmtpServer = "terelay.tycoelectronics.net";//Smtp服务器
                DataTable mailaddressdt = new SQLCommand(System.Configuration.ConfigurationManager.AppSettings["connectionString"], "Mail").
                    ExecuteQueryReturnDT("select * from Mail");

                if (lastsendmailtime=="")
                    lastsendmailtime = DateTime.Now.AddHours(0 - mailinterval).ToString("MMddHHmm");
                if (int.Parse(lastsendmailtime) <= int.Parse(DateTime.Now.AddHours(0 - mailinterval).ToString("MMddHHmm")))
                {
                    lastsendmailtime = DateTime.Now.ToString("MMddHHmm");//更新上次发送的时间
                    string mailaddress = "";
                    //循环加入收件人收箱地址并发送
                    for (int i = 0; i < mailaddressdt.Rows.Count; i++)
                    {
                        if (i == mailaddressdt.Rows.Count - 1)
                            mailaddress += mailaddressdt.Rows[i][0].ToString();
                        else
                            mailaddress += mailaddressdt.Rows[i][0].ToString() + ";";

                    }
                    mail.To = mailaddress;
                    try
                    {
                        System.Web.Mail.SmtpMail.Send(mail);
                    }
                    catch (Exception e1)
                    {
                        string myexce = e1.ToString();
                    }
                }

                if (lastsendphonetime == "")
                    lastsendphonetime = DateTime.Now.AddHours(-1).Hour.ToString();
                //发送短信
                if (int.Parse(lastsendphonetime) <= int.Parse(DateTime.Now.AddHours(-1).Hour.ToString()))
                {
                    lastsendphonetime = DateTime.Now.Hour.ToString();//每隔一小时发短信
                    try
                    {

                        string temp = "<b>" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\nThe Lastestwarning Node:Gateway" +
                                      this.gatewayhardaddr + "<br>" + "Floor:" + this.gatewayaddr + "<br>" + warningjson  + "【TE Warning】";
                        //if(phoneflag=="ON")
                        if (phoneflag == "ON")
                            SendMessage(telephone, temp);
                    }
                    catch (Exception e1)
                    {
                        //lastsendphonetime = DateTime.Now.Minute.ToString();//每隔一小时发短信
                        restr = "发送失败：" + e1;
                    }
                }
            }
        }






        //==============================以下是内部函数===================================================================
        /// <summary>
        /// 向指定的用户发送一定内容的短信息
        /// </summary>
        /// <param name="telephone">手机号,多个号码之间用半角逗号隔开 </param>
        /// <param name="content">发送内容</param>
        /// <returns>是否发送成功</returns>
        public static bool SendMessage(string telephone, string content)
        {
            string extemp = "";
            bool ret = false;
            string[] array = telephone.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
            //组url
            string smsurl = "http://sms.106vip.com/sms.aspx?action=send";  //  请求地址
            smsurl += "&userid=36562";               // 企业id
            smsurl += "&account=ligong215";          // 用户账号
            smsurl += "&password=ligong215";         //用户密码
            smsurl += "&mobile=" + telephone;         //发送的目的号码
            smsurl += "&content=" + content;          //发送内容
            smsurl += "&sendTime=&taskName=[BMM短信]";      //立即发送及任务命令
            smsurl += "&checkcontent=1&mobilenumber=" + array.Length.ToString();    //检测非法字符及本次提交的手机号数量
            smsurl += "&countnumber=" + array.Length.ToString();         //本次提交的号码总数
            smsurl += "&telephonenumber=0";                         //本次提交的小灵通或座机数量

            //http发送
            try
            {
                HttpWebRequest hr = (HttpWebRequest)WebRequest.Create(smsurl);       //建立发送请求
                hr.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
                hr.Method = "GET";
                hr.Timeout = 30 * 60 * 1000;
                WebResponse hs = hr.GetResponse();
                Stream sr = hs.GetResponseStream();
                StreamReader ser = new StreamReader(sr, Encoding.Default);
                //解析返回xmls
                string[] state = readxml(ser.ReadToEnd());
                if (state.Length > 0 && state[0] == "Success")
                {
                    ret = true;
                }
            }
            catch (Exception em)
            {
                extemp = em.ToString();
            }
            return ret;

        }

        /// <summary>
        /// 解析短信平台返回的xml字符串
        /// </summary>
        /// <param name="smsxml">发送命令返回的xml</param>
        /// <returns>解析后保存在字符串内的xml返回值/returns>
        public static string[] readxml(string smsxml)
        {
            //用于存放解析后的xml返回值｛返回状态值，返回信息，返回余额，返回本次任务的序列ID，成功短信数｝
            string[] xmls = { "", "", "", "", "" };

            XmlDocument xmlroot = new XmlDocument();
            xmlroot.LoadXml(smsxml);//加载xml字符串

            XmlNodeList listNodes = null;
            listNodes = xmlroot.SelectNodes("returnsms/returnstatus");//获取返回状态值
            foreach (XmlNode node in listNodes)
            {
                xmls[0] = node.InnerText;
            }
            listNodes = xmlroot.SelectNodes("returnsms/message");//返回信息
            foreach (XmlNode node in listNodes)
            {
                xmls[1] = node.InnerText;
            }
            listNodes = xmlroot.SelectNodes("returnsms/remainpoint");//返回余额
            foreach (XmlNode node in listNodes)
            {
                xmls[2] = node.InnerText;
            }
            listNodes = xmlroot.SelectNodes("returnsms/taskID");//返回本次任务的序列ID
            foreach (XmlNode node in listNodes)
            {
                xmls[3] = node.InnerText;
            }
            listNodes = xmlroot.SelectNodes("returnsms/successCounts");//成功短信数
            foreach (XmlNode node in listNodes)
            {
                xmls[4] = node.InnerText;
            }
            string temp = xmls.ToString();
            return xmls;
        }

        /// <summary>
        /// 获取数据库中两天内的信息，组装后返回
        /// </summary>
        /// <param name="smsxml"></param>
        /// <returns>解析后保存在字符串内的数据库warning数据/returns>
        public string getmailinformation()
        {
            int count = 1;
            string information = "";
            string sqlstrhistory = "";
            var informationtemp = new StringBuilder();
            for (int nodei = 1; nodei < 11; nodei++)
            {
                float nodeup, nodelow, nodedata;
                string nodeistr = nodei.ToString();
                sqlstrhistory = "select currentTime,nodetype" + nodeistr + ",nodeaddr" + nodeistr + ",upperbound" + nodeistr + ",lowerbound" + nodeistr +
                    ",nodedata" + nodeistr + ",gatewayhardaddr" + " from Up where currentTime>='" + DateTime.Now.AddDays(-1).ToString("yyyyMMdd") + "0000'" + " and currentTime<='" +
                    DateTime.Now.ToString("yyyyMMdd") + "2400' order by currentTime desc";
                DataTable myhistorydt = new SQLCommand(System.Configuration.ConfigurationManager.//创建一个数据库的连接对象 
                    AppSettings["connectionString"], "Up").ExecuteQueryReturnDT(sqlstrhistory);
                if (myhistorydt.Rows.Count > 0)
                {
                    for (int i = 0; i < myhistorydt.Rows.Count; i++)
                    {
                        if (count > 100)
                            break;
                        if (myhistorydt.Rows[i][5].ToString() == "0")//若果该节点不存在，直接跳过
                        {
                            continue;
                        }
                        nodedata = float.Parse(myhistorydt.Rows[i][5].ToString());
                        nodeup = float.Parse(myhistorydt.Rows[i][3].ToString());
                        nodelow = float.Parse(myhistorydt.Rows[i][4].ToString());
                        //若果存在warnning
                        if ((nodedata < nodelow || nodedata > nodeup) && nodedata != 0)
                        {
                            string temp1 = myhistorydt.Rows[i][0].ToString();
                            string temp2 = temp1.Substring(0, 4) + "-" + temp1.Substring(4, 2) + "-" + temp1.Substring(6, 2) +
                                " " + temp1.Substring(8, 2) + ":" + temp1.Substring(10, 2) + ":" + temp1.Substring(12, temp1.Length - 12);
                            informationtemp.Append("Warning" + count.ToString() + ", Gateway" + myhistorydt.Rows[i][6] +
                            "Node" + nodeistr + ", " + temp2 + ",Data:" + nodedata.ToString() + ",Max Data:" +
                            nodeup.ToString() + ",Min Data:" + nodelow.ToString() + "<br>");
                            count++;
                        }
                    }
                }
            }
            information = informationtemp.ToString();
            return information;
        }

        /// <summary>
        /// 获取数据库中两天内的信息，组装后返回
        /// </summary>
        /// <param name="smsxml"></param>
        /// <returns>解析后保存在字符串内的数据库warning数据/returns>
        public string getphoneinformation()
        {
            int count = 1;
            string information = "";
            string sqlstrhistory = "";
            var informationtemp = new StringBuilder();
            for (int nodei = 1; nodei < 11; nodei++)
            {
                if (count > 3)//手机短信只发送最近3条，字数限制
                    break;
                int nodeup, nodelow, nodedata;
                string nodeistr = nodei.ToString();
                sqlstrhistory = "select currentTime,nodetype" + nodeistr + ",nodeaddr" + nodeistr + ",upperbound" + nodeistr + ",lowerbound" + nodeistr +
                    ",nodedata" + nodeistr + ",gatewayhardaddr" + " from Up where currentTime>='" + DateTime.Now.AddDays(-1).ToString("yyyyMMdd") + "0000'" + " and currentTime<='" +
                    DateTime.Now.ToString("yyyyMMdd") + "2400' order by currentTime desc";
                DataTable myhistorydt = new SQLCommand(System.Configuration.ConfigurationManager.//创建一个数据库的连接对象 
                    AppSettings["connectionString"], "Up").ExecuteQueryReturnDT(sqlstrhistory);
                if (myhistorydt.Rows.Count > 0)
                {
                    for (int i = 0; i < myhistorydt.Rows.Count; i++)
                    {

                        if (count > 3)//手机短信只发送最近3条，字数限制
                            break;
                        if (myhistorydt.Rows[i][5].ToString() == "0")//若果该节点不存在，直接跳过
                        {
                            continue;
                        }
                        nodeup = int.Parse(myhistorydt.Rows[i][3].ToString()) * 100;
                        nodelow = int.Parse(myhistorydt.Rows[i][4].ToString()) * 100;
                                             nodedata = int.Parse(myhistorydt.Rows[i][5].ToString());
                        //若果存在warnning
                        if (nodedata < nodelow || nodedata > nodeup)
                        {
                            string temp1 = myhistorydt.Rows[i][0].ToString();
                            string temp2 = temp1.Substring(0, 4) + "-" + temp1.Substring(4, 2) + "-" + temp1.Substring(6, 2) +
                                " " + temp1.Substring(8, 2) + ":" + temp1.Substring(10, 2) + ":" + temp1.Substring(12, temp1.Length - 12);
                            informationtemp.Append("Warning" + count.ToString() + ", Gateway" + myhistorydt.Rows[i][6] +
                                "  Node" + nodeistr + ",  " + temp2 + "\n");
                            count++;
                        }
                    }
                }
            }
            information = informationtemp.ToString();
            return information;
        }
    }
}
