
using FANUC;
using fanuc采集;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static fanuc采集.ConDevice;

namespace HttpServer
{
    public partial class Form1 : Form
    {
        string Http_Request_Url = "http://127.0.0.1:5100/fanuc/"; 
        bool _contine = true;//用于线程循环
        private AutoResetEvent autoConnectEvent = new AutoResetEvent(false);//此处需要调用System.Threading;用于触发等待的线程已发生的事件(连接)
        public delegate void RecvAndSendHandler(HttpListenerContext s);//此处需要调用System.Net用于请求和响应HttpListener类
        public event RecvAndSendHandler RecvAndSend;

        AsyncCallback callback;
        HttpListenerContext context = null; 

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.RecvAndSend += new RecvAndSendHandler(HttpListen_RecvAndSend);
            #region 添加监听的信息线程添加到线程池
            WaitCallback wc = new WaitCallback(http_Listen);
            ThreadPool.QueueUserWorkItem(wc);
            label1.Text = "HttpServer已开启：" + Http_Request_Url;
            #endregion 
        }

        /// <summary>
        /// 监听的线程
        /// </summary>
        /// <param name="ob"></param>
        private void http_Listen(object ob)
        {
            callback = new AsyncCallback(acceptCallback);

            HttpListener httpListenner;
            httpListenner = new HttpListener();
            httpListenner.AuthenticationSchemes = AuthenticationSchemes.Anonymous;
            httpListenner.Prefixes.Add(Http_Request_Url);
            httpListenner.Start();
            
            while (_contine)
            {
                try
                {
                    httpListenner.BeginGetContext(callback, httpListenner);
                    autoConnectEvent.WaitOne();
                }
                catch (Exception ex)
                {
                    YG.Log.Instance.WriteLogAdd(">>>===服务异常 : >>>>===" + ex.Message);
                }
                Thread.Sleep(10);
            }
        }
        /// <summary>
        /// 回调函数
        /// </summary>
        /// <param name="ar"></param>
        private void acceptCallback(IAsyncResult ar)
        {
            try
            {
                context = ((HttpListener)ar.AsyncState).EndGetContext(ar);
            }
            catch (Exception)
            {
                autoConnectEvent.Set();
            }
            if (context != null)
            {
                RecvAndSend(context);//触发我们一开始声明的事件
                autoConnectEvent.Set();
            }
        }

        /// <summary>
        /// 接听到消息的方法
        /// </summary>
        /// <param name="cont"></param>
        private void HttpListen_RecvAndSend(HttpListenerContext cont)
        {
            HttpListenerRequest request = cont.Request;
            HttpListenerResponse response = context.Response;
            Servlet servlet = new MyServlet();
            servlet.onCreate();
            try { 
            if (request.HttpMethod == "GET")
            {
                {
                    if (!request.Url.ToString().Contains("favicon"))
                    {
                        string ip = request.QueryString["ip"];
                        string port = request.QueryString["port"];
                        string fun = request.QueryString["fun"];
                        int ret = 0;
                        ConDevice CIF = new ConDevice();

                        switch (fun)
                        {
                            #region 
                            case "All":
                                ConDevice2 CIF2 = new ConDevice2(ip, port);
                                DeviceInfo info = new DeviceInfo();
                                if (CIF2.h > 0)
                                {
                                    info.MainProg = CIF2.MainProg();
                                    info.CurProg = CIF2.MainProg();
                                    info.Status = CIF2.Status();
                                    info.EMG = CIF2.EMG();
                                    info.ActFeed = CIF2.ActFeed();
                                    info.ActSpindle = CIF2.ActSpindle();
                                    info.SpindleLoad = CIF2.SpindleLoad();
                                    info.spindleMagnification = CIF2.spindleMagnification();
                                    info.ServoLoadX = CIF2.ServoLoadX();
                                    info.ServoLoadY = CIF2.ServoLoadY();
                                    info.ServoLoadZ = CIF2.ServoLoadZ();
                                    info.PowerOnTime = CIF2.PowerOnTime();
                                    info.AccumulateCuttingTime = CIF2.AccumulateCuttingTime();
                                    info.CuttingTimePerCycle = CIF2.CuttingTimePerCycle();
                                    info.WorkTime = CIF2.WorkTime();
                                    info.Part_Count = CIF2.Part_Count();

                                    string isalarm = ""; 

                                    //info.AlmMsg = CIF2.AlmMsg(out isalarm);
                                    info.AlmMsg =  CIF2.operationAlarm();

                                    info.IsAlarm = isalarm;
                                    info.ToolNo = CIF2.ToolNo();
                                    info.ToolLife = CIF2.ToolLife();
                                    //info.ToolLife = CIF2.ToolLife(ip, port);

                                    string jsonalldata = JsonConvert.SerializeObject(info);

                                    CIF2.freehand();
                                    AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), jsonalldata);
                                    servlet.onGet(request, response, jsonalldata);
                                }
                                else
                                {
                                    AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), CIF2.h.ToString());
                                    servlet.onGet(request, response, CIF2.h.ToString());
                                }

                                break;
                            case "UploadFile": 
                                try
                                {
                                    string prgname = request.QueryString["prgname"];
                                    YG.Log.Instance.WriteLogAdd(">>>===上传文件名 : >>>>===" + prgname);
                                    ret = CIF.UploadNcProg(ip, port, prgname);
                                    if (ret == Fanuc.EW_OK)
                                    {
                                        AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), "OK");
                                        servlet.onGet(request, response, "0");
                                    }
                                    else
                                    {
                                        AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), ret.ToString());
                                        servlet.onGet(request, response, ret.ToString());
                                    }
                                }
                                catch (Exception uploadex)
                                {
                                    servlet.onGet(request, response, uploadex.Message);
                                }

                                break;
                            case "DeleteNCProgram":
                                try
                                {
                                    string prgname = request.QueryString["prgname"];
                                    ret = CIF.DeleteNcProg(ip, port, prgname);
                                    if (ret == Fanuc.EW_OK)
                                    {
                                        AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), "OK");
                                        servlet.onGet(request, response, "0");
                                    }
                                    else
                                    {
                                        AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), ret.ToString());
                                        servlet.onGet(request, response, ret.ToString());
                                    }
                                }
                                catch (Exception uploadex)
                                {
                                    servlet.onGet(request, response, uploadex.Message);
                                }

                                break;
                            case "SelectNcProgram":
                                try
                                {
                                    string prgname = request.QueryString["prgname"];
                                    YG.Log.Instance.WriteLogAdd(">>>===选择程序文件名 : >>>>===" + prgname);
                                    ret = CIF.SelectedNcProg(ip, port, prgname);
                                    if (ret == Fanuc.EW_OK)
                                    {
                                        AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), "OK");
                                        servlet.onGet(request, response, "0");
                                    }
                                    else
                                    {
                                        AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), ret.ToString());
                                        servlet.onGet(request, response, ret.ToString());
                                    }
                                }
                                catch (Exception uploadex)
                                {
                                    servlet.onGet(request, response, uploadex.Message);
                                }

                                break;
                            case "StartNCProgram":
                                try
                                {
                                    string prgname = request.QueryString["prgname"];
                                    ret = CIF.ReadPmcMarco(ip, port, prgname);
                                    if (ret == Fanuc.EW_OK)
                                    {
                                        AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), "OK");
                                        servlet.onGet(request, response, "0");
                                    }
                                    else
                                    {
                                        AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), ret.ToString());
                                        servlet.onGet(request, response, ret.ToString());
                                    }
                                }
                                catch (Exception uploadex)
                                {
                                    servlet.onGet(request, response, uploadex.Message);
                                }

                                break;
                            // 读写NCDATA
                            case "ReadNcdataMarco":
                                string ncDateaddress = request.QueryString["address"];
                                int ReadncdataMarco = CIF.ReadMacroRange(ip, port, ncDateaddress);
                                AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), "{\"ReadncdataMarco\": \"" + ReadncdataMarco + "\"}");

                                servlet.onGet(request, response, "{\"ReadncdataMarco\": \"" + ReadncdataMarco + "\"}");
                                break;
                            // 读写G54工件坐标系
                            case "ReadWriteZofs":
                                int ReadWriteZofs = CIF.ReadWriteZofs(ip, port);
                                AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), "{\"ReadWriteZofs\": \"" + ReadWriteZofs + "\"}");

                                servlet.onGet(request, response, "{\"ReadWriteZofs\": \"" + ReadWriteZofs + "\"}");
                                break;
                            case "Connect":///连接测试 
                                try
                                {
                                    Ping pingSender = new Ping();
                                    PingReply reply = pingSender.Send(ip);
                                    if (reply.Status!= IPStatus.Success)
                                    {
                                        ret = -16;
                                    }
                                    
                                        //retConnect = Fanuc.cnc_allclibhndl3(ip, Convert.ToUInt16(port), 2, out Fanuc.h);
                                        Thread.Sleep(100);
                                }
                                catch (Exception ex)
                                {
                                    servlet.onGet(request, response, ex.Message);
                                }
                                if (ret == Fanuc.EW_OK)
                                {
                                    AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), "OK");
                                    servlet.onGet(request, response, "0");
                                }
                                else
                                {
                                    AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), ret.ToString());
                                    servlet.onGet(request, response, ret.ToString());
                                }
                                break;


                            case "MainProg":
                                string MainProg = CIF.MainProg(ip, port);
                                AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), "{\"MainProg\": \"" + MainProg + "\"}");
                                servlet.onGet(request, response, "{\"MainProg\": \"" + MainProg + "\"}");
                                break;


                            case "CurProg":
                                string CurProg = CIF.MainProg(ip, port);
                                AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), "{\"CurProg\": \"" + CurProg + "\"}");
                                servlet.onGet(request, response, "{\"CurProg\": \"" + CurProg + "\"}");
                                break;

                            case "Status":
                                string Status = CIF.Status(ip, port);
                                AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), "{\"Status\": \"" + Status + "\"}");
                                servlet.onGet(request, response, "{\"Status\": \"" + Status + "\"}");
                                break;

                            case "Mode":
                                string Mode = CIF.Mode(ip, port);
                                AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), "{\"Mode\": \"" + Mode + "\"}");
                                servlet.onGet(request, response, "{\"Mode\": \"" + Mode + "\"}");
                                break;
                            case "EMG":
                                string EMG = CIF.EMG(ip, port);
                                AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), "{\"EMG\": \"" + EMG + "\"}");
                                servlet.onGet(request, response, "{\"EMG\": \"" + EMG + "\"}");
                                break;
                            case "ActFeed":
                                string ActFeed = CIF.ActFeed(ip, port);
                                AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), "{\"ActFeed\": \"" + ActFeed + "\"}");
                                servlet.onGet(request, response, "{\"ActFeed\": \"" + ActFeed + "\"}");
                                break;                            

                            case "ActSpindle":
                                string ActSpindle = CIF.ActSpindle(ip, port);
                                AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), "{\"ActSpindle\": \"" + ActSpindle + "\"}");
                                servlet.onGet(request, response, "{\"ActSpindle\": \"" + ActSpindle + "\"}");
                                break;
                            case "ServoLoadX":
                                string ServoLoadX = CIF.ServoLoadX(ip, port);
                                AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), "{\"ServoLoadX\": \"" + ServoLoadX + "\"}");
                                servlet.onGet(request, response, "{\"ServoLoadX\": \"" + ServoLoadX + "\"}");
                                break;
                            case "ServoLoadY":
                                string ServoLoadY = CIF.ServoLoadY(ip, port);
                                AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), "{\"ServoLoadY\": \"" + ServoLoadY + "\"}");
                                servlet.onGet(request, response, "{\"ServoLoadY\": \"" + ServoLoadY + "\"}");
                                break;
                            case "ServoLoadZ":
                                string ServoLoadZ = CIF.ServoLoadZ(ip, port);
                                AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), "{\"ServoLoadZ\": \"" + ServoLoadZ + "\"}");
                                servlet.onGet(request, response, "{\"ServoLoadZ\": \"" + ServoLoadZ + "\"}");
                                break;

                            case "PowerOnTime":
                                string PowerOnTime = CIF.PowerOnTime(ip, port);
                                AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), "{\"PowerOnTime\": \"" + PowerOnTime + "\"}");
                                servlet.onGet(request, response, "{\"PowerOnTime\": \"" + PowerOnTime + "\"}");
                                break;

                            case "AccumulateCuttingTime":
                                string AccumulateCuttingTime = CIF.AccumulateCuttingTime(ip, port);
                                AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), "{\"AccumulateCuttingTime\": \"" + AccumulateCuttingTime + "\"}");
                                servlet.onGet(request, response, "{\"AccumulateCuttingTime\": \"" + AccumulateCuttingTime + "\"}");
                                break;



                            case "CuttingTimePerCycle":
                                string CuttingTimePerCycle = CIF.CuttingTimePerCycle(ip, port);
                                AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), "{\"CuttingTimePerCycle\": \"" + CuttingTimePerCycle + "\"}");
                                servlet.onGet(request, response, "{\"CuttingTimePerCycle\": \"" + CuttingTimePerCycle + "\"}");
                                break;



                            case "WorkTime":
                                string WorkTime = CIF.WorkTime(ip, port);
                                AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), "{\"WorkTime\": \"" + WorkTime + "\"}");
                                servlet.onGet(request, response, "{\"WorkTime\": \"" + WorkTime + "\"}");
                                break;



                            case "Part_Count":
                                string Part_Count = CIF.Part_Count(ip, port);
                                AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), "{\"Part_Count\": \"" + Part_Count + "\"}");
                                servlet.onGet(request, response, "{\"Part_Count\": \"" + Part_Count + "\"}");
                                break;



                            case "ToolNo":
                                string ToolNo = CIF.ToolNo(ip, port);
                                AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), "{\"ToolNo\": \"" + ToolNo + "\"}");
                                servlet.onGet(request, response, "{\"ToolNo\": \"" + ToolNo + "\"}");
                                break;

                            case "ToolList":
                                List<Tool> tools = CIF.ToolLife(ip, port);
                                AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), "{\"ToolLife\": \"" + tools + "\"}");
                                servlet.onGet(request, response, JsonConvert.SerializeObject(tools));
                                break;

                            case "AlmInfo":
                                try {
                                    List<ConDevice.AlmInfo> allAlmList = new List<AlmInfo>();
                                    ConDevice2 con2 = new ConDevice2(ip, port);
                                    //实时报警
                                    List<ConDevice.AlmInfo> alms = con2.operationAlarm();
                                    //信息履历
                                    List<ConDevice.AlmInfo> almLL = con2.rdalmhistry5();
                                    if (alms != null && alms.Count() > 0)
                                    {
                                        allAlmList.AddRange(alms);
                                    }
                                    if (almLL != null && almLL.Count() > 0)
                                    {
                                        allAlmList.AddRange(almLL);
                                    }
                                    con2.freehand();
                                    string jsonData = JsonConvert.SerializeObject(allAlmList);
                                    AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), "{\"AlmInfo\": \"" + allAlmList.Count() + "\"}");
                                    servlet.onGet(request, response, jsonData);
                                }
                                catch(Exception ex)
                                {
                                        servlet.onGet(request, response, ex.Message);
                                }
                                
                                break;

                            case "IsAlarm":
                                string state1 = "";
                                List<ConDevice.AlmInfo> s1 = CIF.AlmMsg(ip, port, out state1);
                                AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), "{\"IsAlarm\": \"" + state1 + "\"}");
                                servlet.onGet(request, response, "{\"IsAlarm\": \"" + state1 + "\"}");
                                break;
                            case "NcList":

                                List<ConDevice.NcInfo> ncinfo = CIF.NcList(ip, port);

                                string ncinfojson = JsonConvert.SerializeObject(ncinfo);


                                AddList(DateTime.Now.ToString(), "GET", request.Url.ToString(), "{\"NcList\": \"" + ncinfojson + "\"}");



                                servlet.onGet(request, response, "{\"NcList\": \"" + ncinfojson + "\"}");
                                break; 

                            #endregion
                            default: servlet.onGet(request, response, "无效的请求"); break;
                        } 
                    }
                }
                response.Close();
            }
            else if (request.HttpMethod == "POST")
            { 
            }
            }catch(Exception ex)
            {
                YG.Log.Instance.WriteLogAdd(">>>===服务异常 : >>>>===" + ex.Message);
            }
        }
 

        public class DeviceInfo
        {
            public string MainProg { get; set; }

            public string CurProg
            { get; set; }
            public string Status
            { get; set; }
            public string Mode
            { get; set; }
            public string EMG
            { get; set; }
            public string ActFeed
            { get; set; }
            public string ActSpindle
            { get; set; }
            public string spindleMagnification
            { get; set; }            
            public string SpindleLoad
            { get; set; }           
            public string ServoLoadX
            { get; set; }
            public string ServoLoadY
            { get; set; }
            public string ServoLoadZ
            { get; set; }
            public string PowerOnTime
            { get; set; }

            public string AccumulateCuttingTime
            { get; set; }
            public string CuttingTimePerCycle
            { get; set; }
            public string WorkTime
            { get; set; }
            public string Part_Count
            { get; set; }
            public string IsAlarm
            { get; set; }
            public List<ConDevice.AlmInfo> AlmMsg
            { get; set; }
            public string ToolNo
            { get; set; }
            public string ToolLife
            { get; set; }


        }

        public class Servlet
        {
            public virtual void onGet(System.Net.HttpListenerRequest request, System.Net.HttpListenerResponse response, string info) { }
            public virtual void onPost(System.Net.HttpListenerRequest request, System.Net.HttpListenerResponse response) { }

            public virtual void onCreate()
            {

            }
        }


        public void AddList(string dtime, string type, string url, string res)
        {
            this.Invoke(new Action(delegate ()
            {
                listView1.BeginUpdate();   //数据更新，UI暂时挂起，直到EndUpdate绘制控件，可以有效避免闪烁并大大提高加载速度
                ListViewItem lvi = new ListViewItem();
                lvi.Text = dtime;
                lvi.SubItems.Add(type);
                lvi.SubItems.Add(url);
                lvi.SubItems.Add(res);
                this.listView1.Items.Insert(0, lvi);
                if(this.listView1.Items.Count > 10)
                {
                    this.listView1.Items.Clear();
                }
                this.listView1.EndUpdate();  //结束数据处理，UI界面一次性绘制。}

            }));

        }


        public class MyServlet : Servlet
        {
            public override void onCreate()
            {
                //base.onCreate();
            }

            public override void onGet(HttpListenerRequest request, HttpListenerResponse response, string info)
            {
                Console.WriteLine("GET:" + request.Url);


                byte[] buffer = Encoding.UTF8.GetBytes(info);
                //string sss = request.QueryString["ty"];
                System.IO.Stream output = response.OutputStream;
                output.Write(buffer, 0, buffer.Length);
                // You must close the output stream.
                output.Close();
                //listener.Stop();
            }

            public override void onPost(HttpListenerRequest request, HttpListenerResponse response)
            {
                Console.WriteLine("POST:" + request.Url);
                byte[] res = Encoding.UTF8.GetBytes("OK");
                response.OutputStream.Write(res, 0, res.Length);
            }
        }


    }
}