using System;
using System.IO;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Xml;
using System.Xml.Serialization;
using eu.datex2;

namespace pl.qumak
{
    class Client
    {
        //ścieżka do pliku z certyfikatem
        static string certPath = @"C:\kpd_client_keystore_xxxx.p12";
        //hasło do pliku z certyfikatem
        static string password = @"xxccxxcc";

        //adres web serwisu do pobierania danych o utrudnieniach
        static string pullUrl = "https://xxxx/addiod/ws_v34/snapshotPull";
        //adres web serwisu do wysyłania danych o utrudnieniach
        static string pushUrl = "https://xxxx/addiod/ws_v34/putData";

        public String PullRequest()
        {
            const string action = "http://datex2.eu/wsdl/snapshotPull/2020/pullData";
            String response = CreateRequest(pullUrl, action, null, "pull");
            return response;
        }

        public String PushRequest(MessageContainer messageContainer)
        {
            const string action = "http://datex2.eu/wsdl/simplePush/2020/putData";
            String response = CreateRequest(pushUrl, action, messageContainer, "push");
            return response;
        }

        static String CreateRequest(String url, String action, MessageContainer messageContainer, String method)
        {
            X509Certificate2 cert = new X509Certificate2(File.ReadAllBytes(certPath), password);
            SoapMessage message = new SoapMessage { Certificate = cert };

            XmlElement body = messageContainer != null ? SerializeToXmlElement(messageContainer) : null;
            message.Body = body;
            var result = message.GetXml(true);

            //plik do którego będzie zapisane żądanie do serwera
            result.Save(@"C:\" + method + "_soap_message.xml");
            Console.WriteLine(@"Przygotowano komunikat do wysłania do serwera KPD. Jego treść została zapisana do pliku C:\"+ method + @"_soap_message.xml");
            HttpWebRequest request = CreateWebRequest(url: url, action: action);
            result.Save(request.GetRequestStream());
            String responeString;


            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            using (StreamReader reader = new StreamReader(response.GetResponseStream()))
            {
                responeString = reader.ReadToEnd();
            }
            var resonseXml = SerializeToXmlDocument(responeString);
            //plik do którego będzie zapisana odpowiedź serwera
            resonseXml.Save(@"C:\" + method + "_soap_response.xml");
            Console.WriteLine(@"Odebrano komunikat od serwera KPD. Jego treść została zapisana do pliku C:\" + method + @"_soap_response.xml");
            return responeString;
        }

        static HttpWebRequest CreateWebRequest(String url, String action)
        {
            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
            webRequest.ContentType = @"text/xml; charset=UTF-8";
            webRequest.Accept = @"text/xml";
            webRequest.Method = @"POST";
            webRequest.AllowAutoRedirect = true;
            webRequest.Headers.Add("SOAPAction", action);
            return webRequest;
        }

        public static XmlElement SerializeToXmlElement(object o)
        {
            XmlDocument doc = new XmlDocument();
            using (XmlWriter writer = doc.CreateNavigator().AppendChild())
            {
                new XmlSerializer(o.GetType()).Serialize(writer, o);
            }
            return doc.DocumentElement;
        }

        public static XmlDocument SerializeToXmlDocument(object o)
        {
            XmlDocument doc = new XmlDocument();
            using (XmlWriter writer = doc.CreateNavigator().AppendChild())
            {
                new XmlSerializer(o.GetType()).Serialize(writer, o);
            }
            return doc;
        }


    }
}
