using System;
using System.Security.Cryptography;
using System.Text;
using System.Net;
using System.IO;
using System.Collections.Specialized;

namespace TestDES
{
	/// <summary>
	/// AllcomUtil 的摘要说明。
	/// </summary>
	public class AllcomUtil
	{
		private string userid;
		private string pass;
		private int type;
		private string deskey;

		public AllcomUtil(string userid,string pass,int type,string deskey)
		{
			this.userid = userid;
			this.pass = pass;
			this.type= type;
			this.deskey = deskey;
		}


		public string getHttp(string url) 
		{
			HttpWebRequest request = null;
			HttpWebResponse response = null;

			try
			{
				request = (HttpWebRequest)WebRequest.Create(url);
				request.ContentType = "application/x-www-form-urlencoded";
				request.Method = "GET";
				request.Headers.Add("Authorization",getAuth());
				response = (HttpWebResponse)request.GetResponse();

				Stream dataStream = response.GetResponseStream();
				StreamReader reader = new StreamReader(dataStream);
				string responseFromServer = reader.ReadToEnd();
				reader.Close();
				dataStream.Close();
				response.Close();
				return responseFromServer;
				
			}
			catch(WebException webex)
			{
				throw webex;
			}

		}

		
		public string sendFax(string url, NameValueCollection nvcdata,NameValueCollection nvcfile) 
		{
			HttpWebRequest request = null;
			HttpWebResponse response = null;

			string boundary = DateTime.Now.Ticks.ToString("x");
			byte[] boundarybyte = System.Text.Encoding.ASCII.GetBytes("\r\n--"+boundary+"\r\n");

			request = (HttpWebRequest)WebRequest.Create(url);
			request.ContentType = "multipart/form-data; boundary=" + boundary;
			request.Method = "POST";
			request.Headers.Add("Authorization",getAuth());
			request.KeepAlive = true;


			Stream stream = request.GetRequestStream();

			string formdata = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
			foreach (string key in nvcdata.Keys)
			{

				stream.Write(boundarybyte, 0, boundarybyte.Length);
				string formitem = string.Format(formdata, key, nvcdata[key]);
				byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
				stream.Write(formitembytes, 0, formitembytes.Length);
			}


			string formfile = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
			foreach (string key in nvcfile.Keys)
			{
				FileInfo file = new FileInfo(nvcfile[key]);
				if(!file.Exists)
				{
					throw  new Exception("没有找到文件:"+file.FullName);
				}

				stream.Write(boundarybyte, 0, boundarybyte.Length);
				string formitem = string.Format(formfile, key, file.Name,"application/octet-stream");
				byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
				stream.Write(formitembytes, 0, formitembytes.Length);

				FileStream fstream = new FileStream(file.FullName, FileMode.Open, FileAccess.Read);
				byte[] buffer = new byte[4096];
				int bytesRead = 0;
				while ((bytesRead = fstream.Read(buffer, 0, buffer.Length)) != 0) 
				{
					stream.Write(buffer, 0, bytesRead);
				}
				fstream.Close();

			}

			byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
			stream.Write(trailer, 0, trailer.Length);

			
			stream.Flush();
			stream.Close();


			string responseFromServer = null;
			try 
			{
				response = (HttpWebResponse)request.GetResponse();
				Stream dataStream = response.GetResponseStream();
				StreamReader reader = new StreamReader(dataStream);
				responseFromServer = reader.ReadToEnd();
				reader.Close();
				dataStream.Close();
				response.Close();

			}
			catch(Exception ex) 
			{
				throw ex;
			}
			
			return responseFromServer;

		}

		//定义标准时间1970后的秒数
		protected static readonly DateTime unixTPStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); 
		//把时间转成timestamp
		public long toUTP(DateTime dt)   
		{   
			TimeSpan toNow = dt.Subtract(unixTPStart);   
			return (long)Math.Round(toNow.TotalMilliseconds);   
		} 


		private String getAuth()
		{
			if(type==0)
			{
				return "basic " + EncodeTo64(userid+":"+pass);
			}
			else if(type==1)
			{
				return "md5 " + EncodeTo64(userid+":"+md5Encrypt(pass));
			}
			else if(type==2)
			{
				if(deskey==null)
				{
					return null;
				}
				string des = desEncrypt(pass+"$"+toUTP(DateTime.Now),deskey);
				return "des " + EncodeTo64(userid+":"+des);
			}
			return null;
		}


		private string desEncrypt(string pToEncrypt, string sKey)
		{
 
			using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
			{
				byte[] inputByteArray = Encoding.UTF8.GetBytes(pToEncrypt);
				des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
				des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
				des.Mode = System.Security.Cryptography.CipherMode.ECB;

				System.IO.MemoryStream ms = new System.IO.MemoryStream();

				

				using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write))
				{
					cs.Write(inputByteArray, 0, inputByteArray.Length);
					cs.FlushFinalBlock();
					cs.Close();
				}
			
				string str = Convert.ToBase64String(ms.ToArray());

				ms.Close();
				return str;
			} 
		}
		//进行md5加密
		private string md5Encrypt(string str)
		{
			MD5 md5=new MD5CryptoServiceProvider();
			byte[] data=System.Text.Encoding.Default.GetBytes(str);
			byte[] result=md5.ComputeHash(data);
			String ret="";
			for(int i=0;i<result.Length;i++)
				ret+=result[i].ToString("x").PadLeft(2,'0');
			return ret;
		}

		private string EncodeTo64(string toEncode)
		{
			byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(toEncode);
			string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
			return returnValue;
		}

	}
}
