using System;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using Newtonsoft.Json;

namespace BRServer
{
    public class NASDK
    {
        public bool isHttp = false;
        string m_logfile = "wk_na.txt";
        string m_pltip;
        string m_appid;
        string m_appsecret;
        int m_pltPort;
        string m_p12certfile;
        string m_certpassword;
        public NASDK(string platformIP, int port, string appId, string appSecret, string p12cert, string certpassword)
        {
            this.m_pltip = platformIP;
            this.m_appid = appId;
            this.m_appsecret = appSecret;
            this.m_pltPort = port;
            this.m_p12certfile = p12cert;
            this.m_certpassword = certpassword;
        }
        public TokenResult getToken()
        {
            TokenResult result = null;

            string apiPath = "/iocm/app/sec/v1.1.0/login";
            string body = "appId=" + this.m_appid + "&secret=" + this.m_appsecret;
            string method = "POST";
            string contenttype = "application/x-www-form-urlencoded";
            WebHeaderCollection headers = new WebHeaderCollection();
            try
            {
                ApiResult apiresult = PostUrl(apiPath, body, headers, method, contenttype, this.m_p12certfile, this.m_certpassword);
                TokenResult tr = JsonConvert.DeserializeObject<TokenResult>(apiresult.result);
                result = tr;
            }
            catch (Exception ex)
            {
                result = null;
                throw ex;
            }
            return result;
        }

        public int sendCommand(string token, string deviceId, string callbackurl, string serviceId, string commandId, CommandPara para,CasicSession session)
        {
            int result = 0;
            string apiPath = string.Format("/iocm/app/cmd/v1.4.0/deviceCommands?appId={0}", this.m_appid);

            SendCommandRequest scr = new SendCommandRequest();
            scr.deviceId = deviceId;
            scr.callbackUrl = callbackurl;
            scr.command = new Command();
            scr.command.method = commandId;
            scr.command.serviceId = serviceId;
            scr.command.paras = "#commandparas#";
            scr.expireTime = 0;
            string body = JsonConvert.SerializeObject(scr);
            string parabody = string.Format("{{\"{0}\":\"{1}\"}}", para.paraName, para.paraValue);

            body = body.Replace("\"#commandparas#\"", parabody);

            string method = "POST";
            string contenttype = "application/json";
            WebHeaderCollection headers = new WebHeaderCollection();
            headers.Add("app_key", this.m_appid);
            headers.Add("Authorization", "Bearer " + token);

            try
            {
                ApiResult apiresult = PostUrl(apiPath, body, headers, method, contenttype, this.m_p12certfile, this.m_certpassword);

                result = apiresult.statusCode;
            }
            catch (Exception ex)
            {
                result = 0;
                throw ex;
            }
            return result;
        }

        private void log(string msg)
        {
            File.AppendAllText(this.m_logfile, msg);
        }

        public class ApiResult
        {
            public int statusCode;
            public string result;
            public string errcode;
            public string memo;
        }

        private ApiResult PostUrl(string apiPath, string postData, WebHeaderCollection headers, string method, string contenttype, string p12certfile, string cerpassword)
        {
            string url = string.Format("https://{0}:{1}{2}", this.m_pltip, this.m_pltPort, apiPath);

            ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);
            ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
            HttpWebRequest httpRequest = (HttpWebRequest)HttpWebRequest.Create(url);
            X509Certificate2 cerCaiShang = new X509Certificate2(p12certfile, cerpassword);

            httpRequest.ClientCertificates.Add(cerCaiShang);
            httpRequest.Method = method;
            httpRequest.ContentType = contenttype;
            httpRequest.Referer = null;
            httpRequest.AllowAutoRedirect = true;
            httpRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";
            httpRequest.Accept = "*/*";
            for (int i = 0; i < headers.Count; i++)
            {
                for (int j = 0; j < headers.GetValues(i).Length; j++)
                {
                    httpRequest.Headers.Add(headers.Keys[i], headers.GetValues(i)[j]);
                }

            }

            if (method != "GET")
            {
                Stream requestStem = httpRequest.GetRequestStream();
                StreamWriter sw = new StreamWriter(requestStem);
                sw.Write(postData);
                sw.Close();
            }

            HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse();
            Stream receiveStream = httpResponse.GetResponseStream();
            string result = string.Empty;
            using (StreamReader sr = new StreamReader(receiveStream))
            {
                result = sr.ReadToEnd();
            }
            ApiResult r = new ApiResult();
            r.result = result;
            r.statusCode = (int)httpResponse.StatusCode;

            return r;
        }

        public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            if (sslPolicyErrors == SslPolicyErrors.None)
                return true;
            return true;
        }
    }
}
