using System;
using System.Linq;
using System.Security.Principal;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.UI.WebControls;

namespace BeWoPlanerMobil.Util
{
	public class CustomBasicAuthorizeAttribute : AuthorizeAttribute
	{
		public bool RequireSsl { get; set; }

		private void CacheValidateHandler(HttpContext context, object data, ref HttpValidationStatus validationStatus)
		{
			validationStatus = OnCacheAuthorization(new HttpContextWrapper(context));
		}

		public override void OnAuthorization(AuthorizationContext filterContext)
		{
			if(filterContext == null)
				throw new ArgumentNullException("filterContext");

			if (!Authenticate(filterContext.HttpContext))
			{
				filterContext.Result = new HttpCustomBasicUnauthorizedResult();
			}
			else
			{
				if (AuthorizeCore(filterContext.HttpContext))
				{
					var cachePolicy = filterContext.HttpContext.Response.Cache;
					cachePolicy.SetProxyMaxAge(new TimeSpan(0));
					cachePolicy.AddValidationCallback(CacheValidateHandler, null);
				}
				else
				{
					filterContext.Result = new HttpCustomBasicUnauthorizedResult();
				}
			}
		}

		private bool Authenticate(HttpContextBase context)
		{
			if (RequireSsl && !context.Request.IsSecureConnection && !context.Request.IsLocal)
				return false;

			if (!context.Request.Headers.AllKeys.Contains("Authorization"))
				return false;

			var authHeader = context.Request.Headers["Authorization"];

			IPrincipal principal;
			if (!TryGetPrincipal(authHeader, out principal)) 
				return false;

			HttpContext.Current.User = principal;
			return true;
		}

		private bool TryGetPrincipal(string authHeader, out IPrincipal principal)
		{
			var creds = ParseAuthHeader(authHeader);
			if(creds != null)
				if (TryGetPrincipal(creds[0], creds[1], out principal))
					return true;

			principal = null;
			return false;
		}

		private bool TryGetPrincipal(string userName, string password, out IPrincipal principal)
		{
			// Principal konstruieren
			throw new NotImplementedException();
		}

		private string[] ParseAuthHeader(string authHeader)
		{
			if (string.IsNullOrEmpty(authHeader) || !authHeader.StartsWith("Basic")) 
				return null;

			var base64Credentials = authHeader.Substring(6);
			var credentials = Encoding.ASCII.GetString(Convert.FromBase64String(base64Credentials)).Split(new[] {':'});

			if (credentials.Length != 2 || string.IsNullOrEmpty(credentials[0]) || string.IsNullOrEmpty(credentials[0])) 
				return null;

			return credentials;
		}
	}
}