using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Maser.Feanor.Model;
using System.Net;
using Maser.Feanor.Biz;


namespace Maser.Feanor.Server
{
    public class Yun020208 : Server
    {
        public const ServerType SERVERTYPE = ServerType.Yun020208;


        public Yun020208(Chamber Chamber) : base(Chamber)
        {
            _chamber = Chamber;
        }


        // Return a list of standard defined sensors for Yun020208
        public override List<Sensor> StandardSensors()
        {
            
            List<Sensor> sensors = new List<Sensor>();
            sensors.Add(new Sensor(-1, 0,  _chamber.PK, "Pt100", SensorType.Pt100, true, false));
            sensors.Add(new Sensor(-1, 1,  _chamber.PK, "Pt100", SensorType.Pt100, false, false));
            sensors.Add(new Sensor(-1, 2,  _chamber.PK, "Thermocouple K", SensorType.ThermocoupleK, false, false));
            sensors.Add(new Sensor(-1, 3,  _chamber.PK, "Thermocouple K", SensorType.ThermocoupleK, false, false));
            for (int i = 4; i < 12; i++)
                sensors.Add(new Sensor(-1, i,  _chamber.PK, String.Format("Voltage #{0:00}", i), SensorType.Voltage,false , false));
            sensors.Add(new Sensor(-1, 12,  _chamber.PK, "RH psychrometer", SensorType.PsychrometerRH, false, false));
            sensors.Add(new Sensor(-1, 13,  _chamber.PK, "RH pressurecooker", SensorType.PressurecookerRH, false, false));
            return sensors;  

        }
            

      


        public override bool Read()
        {
            _Results = new List<Result>();

            string url = URL + "ContentToClient";
            string data;
            try
            {
                using (WebClient client = new WebClient())
                {
                    
                    data = client.DownloadString(url);
                    String[] objects = data.Split(';');
                    foreach (String obj in objects)
                    {
                        try
                        {
                            // Create Results from data-string
                            if (obj.Trim().StartsWith("<D>") && obj.Trim().EndsWith("</D>"))
                            {
                                string s = obj.Replace("<D>", "").Replace("</D>", "").Trim();
                                string[] vars = s.Split(',');
                                int ID = int.Parse(vars[0]);
                                DateTime dt = Time.UnixToDatetime(int.Parse(vars[1]));
                                float fValue = float.Parse(vars[2]);
                                int calibrationPK = int.Parse(vars[3]);
                                Int32 sensorPK = _Sensors.Find(delegate (Sensor sensor) { return (sensor.ID == ID); }).PK;

                                _Results.Add(new Result(-1, sensorPK, fValue, dt, calibrationPK));
                            }
                        }
                        catch
                        {
                            // Continue with next object, ignoring exception
                        }
                    }
                }
            }
            catch
            {
                return false;
            }
            return true;
        }



        public override bool WriteDatetime(DateTime dt)
        {   
            // Format: <time>,[unix timestamp],</time>

            string http = "<time>,";
            http += string.Format("{0},", Time.DatetimeToUnix(dt));
            http += "</time>";
            return HTTP_POST(http);
        }


        public override Boolean WriteInterval(Int32 Interval)
        {
            // Format: <interval>,[interval],</interval>
            string http = "<interval>,";
            http += string.Format("{0},", Interval);
            http += "</interval>";
            return HTTP_POST(http);
        }


        public override bool WriteSensors()
        {
            bool result = true;
            foreach (Sensor sensor in _Sensors)
            {
                Calibration cal = _Calibrations.Find(delegate (Calibration c) { return (c.SensorPK == sensor.PK); });
                if (cal == null)
                    cal = new Calibration(-1, sensor.PK, DateTime.Now, DateTime.Now, DateTime.Now, new double[2] { 0, 1 }, 0, new double[4] { 0, 0, 1, 1 });

                if (!ModifySensor(sensor, cal))
                    result = false;
            }
            return result;
        }



        public override bool ModifySensor(Sensor sensor, Calibration calibration)
        {
            // Format: <sensor>,ID,[Enabled:1/0],[ApplyCalibration:1/0],Description,CalibrationPK,c0,c1,...cn
            string sensorHTTP = "";
            sensorHTTP += "<sensor>,";
            sensorHTTP += sensor.ID.ToString() + ",";
            sensorHTTP += (sensor.Enabled) ? "1," : "0,";
            sensorHTTP += (sensor.ApplyCalibration) ? "1," : "0,";
            sensorHTTP += sensor.Description + ",";
            sensorHTTP += calibration.PK.ToString() + ",";
            sensorHTTP += String.Join(",", calibration.Coefficients);
            sensorHTTP += "</sensor>";
            return HTTP_POST(sensorHTTP);
        }


        private bool HTTP_POST(string http)
        {
            /*
            var reqparm = new System.Collections.Specialized.NameValueCollection();
            reqparm.Add("param1", "<any> kinds & of = ? strings");
            reqparm.Add("param2", "escaping is already handled");
            byte[] responsebytes = client.UploadValues("http://localhost", "POST", reqparm);
            string responsebody = Encoding.UTF8.GetString(responsebytes);
            */
            try
            {
                using (WebClient wc = new WebClient())
                {
                    wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
                    string HtmlResult = wc.UploadString(URL, http);
                    if (HtmlResult != "OK")
                        return false;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return true;
        }
    }




}
