using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Logging;
using ServiceStack.Web;
using System;
using System.Collections.Generic;
namespace MediaBrowser.Api
{
    public class AuthorizationRequestFilterAttribute : Attribute, IHasRequestFilter
    {
        //This property will be resolved by the IoC container
        /// 
        /// Gets or sets the user manager.
        /// 
        /// The user manager.
        public IUserManager UserManager { get; set; }
        public ISessionManager SessionManager { get; set; }
        /// 
        /// Gets or sets the logger.
        /// 
        /// The logger.
        public ILogger Logger { get; set; }
        /// 
        /// The request filter is executed before the service.
        /// 
        /// The http request wrapper
        /// The http response wrapper
        /// The request DTO
        public void RequestFilter(IRequest request, IResponse response, object requestDto)
        {
            //This code is executed before the service
            var auth = GetAuthorizationDictionary(request);
            if (auth != null)
            {
                User user = null;
                if (auth.ContainsKey("UserId"))
                {
                    var userId = auth["UserId"];
                    if (!string.IsNullOrEmpty(userId))
                    {
                        user = UserManager.GetUserById(new Guid(userId));
                    }
                }
                string deviceId;
                string device;
                string client;
                string version;
                auth.TryGetValue("DeviceId", out deviceId);
                auth.TryGetValue("Device", out device);
                auth.TryGetValue("Client", out client);
                auth.TryGetValue("Version", out version);
                if (!string.IsNullOrEmpty(client) && !string.IsNullOrEmpty(deviceId) && !string.IsNullOrEmpty(device) && !string.IsNullOrEmpty(version))
                {
                    var remoteEndPoint = request.RemoteIp;
                    SessionManager.LogSessionActivity(client, version, deviceId, device, remoteEndPoint, user);
                }
            }
        }
        /// 
        /// Gets the auth.
        /// 
        /// The HTTP req.
        /// Dictionary{System.StringSystem.String}.
        private static Dictionary GetAuthorizationDictionary(IRequest httpReq)
        {
            var auth = httpReq.Headers["Authorization"];
            return GetAuthorization(auth);
        }
        public static User GetCurrentUser(IRequest httpReq, IUserManager userManager)
        {
            var info = GetAuthorization(httpReq);
            return string.IsNullOrEmpty(info.UserId) ? null : 
                userManager.GetUserById(new Guid(info.UserId));
        }
        /// 
        /// Gets the authorization.
        /// 
        /// The HTTP req.
        /// Dictionary{System.StringSystem.String}.
        public static AuthorizationInfo GetAuthorization(IRequest httpReq)
        {
            var auth = GetAuthorizationDictionary(httpReq);
            string userId = null;
            string deviceId = null;
            string device = null;
            string client = null;
            string version = null;
            if (auth != null)
            {
                auth.TryGetValue("UserId", out userId);
                auth.TryGetValue("DeviceId", out deviceId);
                auth.TryGetValue("Device", out device);
                auth.TryGetValue("Client", out client);
                auth.TryGetValue("Version", out version);
            }
            return new AuthorizationInfo
            {
                Client = client,
                Device = device,
                DeviceId = deviceId,
                UserId = userId,
                Version = version
            };
        }
        /// 
        /// Gets the authorization.
        /// 
        /// The authorization header.
        /// Dictionary{System.StringSystem.String}.
        private static Dictionary GetAuthorization(string authorizationHeader)
        {
            if (authorizationHeader == null) return null;
            var parts = authorizationHeader.Split(' ');
            // There should be at least to parts
            if (parts.Length < 2) return null;
            // It has to be a digest request
            if (!string.Equals(parts[0], "MediaBrowser", StringComparison.OrdinalIgnoreCase))
            {
                return null;
            }
            // Remove uptil the first space
            authorizationHeader = authorizationHeader.Substring(authorizationHeader.IndexOf(' '));
            parts = authorizationHeader.Split(',');
            var result = new Dictionary(StringComparer.OrdinalIgnoreCase);
            foreach (var item in parts)
            {
                var param = item.Trim().Split(new[] { '=' }, 2);
                result.Add(param[0], param[1].Trim(new[] { '"' }));
            }
            return result;
        }
        /// 
        /// A new shallow copy of this filter is used on every request.
        /// 
        /// IHasRequestFilter.
        public IHasRequestFilter Copy()
        {
            return this;
        }
        /// 
        /// Order in which Request Filters are executed.
        /// <0 Executed before global request filters
        /// >0 Executed after global request filters
        /// 
        /// The priority.
        public int Priority
        {
            get { return 0; }
        }
    }
    public class AuthorizationInfo
    {
        public string UserId;
        public string DeviceId;
        public string Device;
        public string Client;
        public string Version;
    }
}