using System;
using System.Net;
using System.Collections;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Diagnostics;

namespace Lumpio.Net.Msn {
	public class PassportAuthenticator {
		//const string NexusURL = "https://nexus.passport.com/rdr/pprdr.asp";
		
		public static string GetTicket(string passport, string password, string authstring) {
			HttpWebRequest req;
			HttpWebResponse resp;
			string loginurl;
			int tries = 3;
			
			ServicePointManager.CertificatePolicy = new TrustAllPolicy();
			
			//req = (HttpWebRequest)WebRequest.Create(NexusURL);
			
			//Console.WriteLine("PASSPORTAUTH: Connecting to Passport Nexus...");
			//resp = req.GetResponse();
			
			loginurl = "https://login.passport.com/login2.srf";
			
			while (tries-- > 0) {
				string authenticate;
				string[] values;
				//Hashtable fields;
				
				req = (HttpWebRequest)WebRequest.Create(loginurl);
				req.Headers["Authorization"] = "Passport1.4 OrgVerb=GET,OrgURL=http%3A%2F%2Fmessenger%2Emsn%2Ecom,sign-in=" + MsnClient.URLEncode(passport) + ",pwd=" + MsnClient.URLEncode(password) + "," + authstring;
				
				Debug.WriteLine("PASSPORT: Connecting to login server");
				resp = (HttpWebResponse)req.GetResponse();
				
				if ((values = resp.Headers.GetValues("Authentication-Info")) != null) {
					authenticate = values[0];
				} else if ((values = resp.Headers.GetValues("WWW-Authenticate")) != null) {
					authenticate = values[0];
				} else {
					throw new Exception("Passport headers missing?!");
				}
				
				switch (resp.StatusCode) {
					case HttpStatusCode.OK:
						int start = authenticate.IndexOf("from-PP='") + 9;
						int end = authenticate.IndexOf("'", start);
						string ticket = authenticate.Substring(start, end - start);
						
						return ticket;
					case HttpStatusCode.Found:
						Debug.WriteLine("PASSPORT: Redirected!");
						return null;
					case HttpStatusCode.Unauthorized:
						Debug.WriteLine("PASSWORD: Authorization error!");
						return null;
				}
			}
			return null;
		}
	}
	
	public class TrustAllPolicy : ICertificatePolicy {
 		public bool CheckValidationResult(ServicePoint sp, X509Certificate cert, WebRequest req, int p) {
  			return true;
  		}
 	}
 	
 	public class HexMD5 {
 		public static string Hash(string s) {
 			string hexDigits = "0123456789abcdef";
 			
			byte[] digest = MD5.Create()
				.ComputeHash(System.Text.Encoding.UTF8.GetBytes(s));
			string r = "";
			
			for (int i = 0; i < digest.Length; ++i) {
				byte b = digest[i];
				r += hexDigits.Substring(b >> 4, 1);
				r += hexDigits.Substring(b & 0x0F, 1);
			}
			
			return r;
		}
	}
}
