using System;
using System.Collections;
using System.IO;
using System.Net;
using System.Text;
using System.Web;
using System.Xml;
using System.Diagnostics;
using System.Windows.Forms;
using System.Collections.Generic;

namespace SiaSun.LMS.Common
{
    public class WebServer
    {
        private Hashtable _xmlNamespaces = new Hashtable();

        private string _Name = SiaSun.LMS.Common.StringUtil.GetConfig("wsUserName");

        private string _PassWord = SiaSun.LMS.Common.StringUtil.GetConfig("wsUserPsd");

        public WebServer(string Name, string PassWord)
        {
            if (!string.IsNullOrEmpty(Name))
            {
                this._Name = Name;
            }

            if (!string.IsNullOrEmpty(PassWord))
            {
                this._PassWord = PassWord;
            }
        }

        private static void AddDelaration(XmlDocument doc)
        {
            XmlDeclaration newChild = doc.CreateXmlDeclaration("1.0", "utf-8", null);

            doc.InsertBefore(newChild, doc.DocumentElement);
        }

        private byte[] EncodePars(List<DictionaryEntry> Pars)
        {
            return Encoding.UTF8.GetBytes(ParsToString(Pars));
        }

        private byte[] EncodeParsToSoap(List<DictionaryEntry> Pars, string XmlNs, string MethodName)
        {
            string str = string.Format("<soapenv:Header><ns1:username soapenv:actor=\"http://schemas.xmlsoap.org/soap/actor/next\" soapenv:mustUnderstand=\"0\" xsi:type=\"soapenc:string\" xmlns:ns1=\"Authorization\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">{0}</ns1:username> <ns2:password soapenv:actor=\"http://schemas.xmlsoap.org/soap/actor/next\" soapenv:mustUnderstand=\"0\" xsi:type=\"soapenc:string\" xmlns:ns2=\"Authorization\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">{1}</ns2:password> </soapenv:Header>",this._Name,this._PassWord);

            XmlDocument doc = new XmlDocument();

            doc.LoadXml("<soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">" + str + "</soapenv:Envelope>");
            
            AddDelaration(doc);
            
            XmlElement newChild = doc.CreateElement("soapenv", "Body", "http://schemas.xmlsoap.org/soap/envelope/");
            
            XmlElement element2 = doc.CreateElement(MethodName);
           
            element2.SetAttribute("xmlns", XmlNs);

            for (int i = 0; i < Pars.Count; i++)
            {
                XmlElement element3 = doc.CreateElement(Pars[i].Key.ToString());

                element3.SetAttribute("xsi:type", "xsd:string");

                element3.InnerText = Pars[i].Value.ToString();

                element2.AppendChild(element3);
            }

            newChild.AppendChild(element2);

            doc.DocumentElement.AppendChild(newChild);

            return Encoding.UTF8.GetBytes(doc.OuterXml);
        }

        private  string GetNamespace(string URL)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL + "?WSDL");
            SetWebRequest(request);
            try
            {
                StreamReader reader = new StreamReader(request.GetResponse().GetResponseStream(), Encoding.UTF8);
                XmlDocument document = new XmlDocument();
                document.LoadXml(reader.ReadToEnd());
                return document.SelectSingleNode("//@targetNamespace").Value;
            }
            catch (WebException exception)
            {
                string str = exception.Status.ToString();
            //    MessageBox.Show("******** call webservice GetNamespace err ******** ���ӷ����� ��ȡ WSDL ���� *******  " + exception.Message);
                return (" ����" + exception.Message.ToString());
            }
        }

        private string ParsToString(List<DictionaryEntry> Pars)
        {
            StringBuilder builder = new StringBuilder();

            for (int i = 0; i < Pars.Count; i++)
            {
                if (builder.Length > 0)
                {
                    builder.Append("&");
                }
                builder.Append(HttpUtility.UrlEncode(Pars[i].Key.ToString()) + "=" + HttpUtility.UrlEncode(Pars[i].Key.ToString()));
            }
            return builder.ToString();
        }

        public XmlDocument QueryGetWebService(string URL, string MethodName, List<DictionaryEntry> Pars)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL + "/" + MethodName + "?" + ParsToString(Pars));
            request.Method = "GET";
            request.ContentType = "application/x-www-form-urlencoded";
            SetWebRequest(request);
            return ReadXmlResponse(request.GetResponse());
        }

        public XmlDocument QueryPostWebService(string URL, string MethodName, List<DictionaryEntry> Pars)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL + "/" + MethodName);
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            SetWebRequest(request);
            byte[] data = EncodePars(Pars);
            WriteRequestData(request, data);
            return ReadXmlResponse(request.GetResponse());
        }

        public XmlDocument QuerySoapWebService(string URL, string MethodName, List<DictionaryEntry> Pars)
        {
            if (_xmlNamespaces.ContainsKey(URL))
            {
                return QuerySoapWebService(URL, MethodName, Pars, _xmlNamespaces[URL].ToString());
            }
            string xmlNs = GetNamespace(URL);
            int index = xmlNs.IndexOf("����");
            if (0 < index)
            {
                return null;
            }
            return QuerySoapWebService(URL, MethodName, Pars, xmlNs);
        }

        private XmlDocument QuerySoapWebService(string URL, string MethodName, List<DictionaryEntry> Pars, string XmlNs)
        {
            _xmlNamespaces[URL] = XmlNs;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
            XmlDocument document = new XmlDocument();
            XmlDocument doc = new XmlDocument();
            try
            {
                request.Method = "POST";
                request.ContentType = "text/xml; charset=utf-8";
                request.Headers.Add("SOAPAction", "\"" + XmlNs + (XmlNs.EndsWith("/") ? "" : "/") + MethodName + "\"");
                SetWebRequest(request);
                byte[] data = this.EncodeParsToSoap(Pars, XmlNs, MethodName);
                WriteRequestData(request, data);
                document = ReadXmlResponse(request.GetResponse());
            }
            catch (Exception e)
            {
                string str = e.Message.ToString();

                return null;
            }

            XmlNamespaceManager nsmgr = new XmlNamespaceManager(document.NameTable);
            nsmgr.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
            doc.LoadXml("<root>" + document.SelectSingleNode("//soap:Body/*", nsmgr).InnerXml + "</root>");
            AddDelaration(doc);
            return doc;
        }

        private XmlDocument ReadXmlResponse(WebResponse response)
        {
            StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
            string xml = reader.ReadToEnd();
            reader.Close();
            XmlDocument document = new XmlDocument();
            document.LoadXml(xml);
            return document;
        }

        private void SetWebRequest(HttpWebRequest request)
        {
            request.Credentials = CredentialCache.DefaultCredentials;
            request.Timeout = 0x8710;
        }

        private void WriteRequestData(HttpWebRequest request, byte[] data)
        {
            request.ContentLength = data.Length;
            System.IO.Stream requestStream = request.GetRequestStream();
            requestStream.Write(data, 0, data.Length);
            requestStream.Close();
        }
    }
}