using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Fuel.Core.WechatServer
{
    public class WechatUserSessionWrapper
    {
        public WechatUserSessionResponse UserSession { get; set; }
        public DateTime InitTime { get; set; }
    }

    public static class WechatUserSessionRepo
    {
        private static Dictionary<string, WechatUserSessionWrapper> _userSessions =
            new Dictionary<string, WechatUserSessionWrapper>();
        private static readonly object _lockObj = new object();

        private static TimeSpan SessionMaxTime = new TimeSpan(3, 0, 0, 0); // 3 days

        public static void AddUserSession(string thirdSessionKey, WechatUserSessionResponse userSession)
        {
            CleanupUserSessions();

            var userSessionWrapper = new WechatUserSessionWrapper { UserSession = userSession, InitTime = DateTime.Now };
            lock (_lockObj)
            {
                if (_userSessions.ContainsKey(thirdSessionKey))
                {
                    _userSessions.Remove(thirdSessionKey);
                }
                _userSessions.Add(thirdSessionKey, userSessionWrapper);
            }
        }

        public static WechatUserSessionResponse GetUserSession(string thirdSessionKey)
        {
            CleanupUserSessions();

            lock (_lockObj)
            {
                try
                {
                    var userSessionWrapper = _userSessions[thirdSessionKey];
                    return userSessionWrapper.UserSession;
                }
                catch (Exception)
                {
                    return null;
                }
            }
        }

        public static bool RemoveUserSession(string unionId)
        {
            CleanupUserSessions();

            lock (_lockObj)
            {
                try
                {
                    foreach (var item in _userSessions.Where(p =>
                        String.Compare(p.Value.UserSession.unionid, unionId, StringComparison.Ordinal) == 0).ToList())
                    {
                        _userSessions.Remove(item.Key);
                        return true;
                    }
                    return false;
                }
                catch (Exception)
                {
                    return false;
                }
            }
        }

        private static void CleanupUserSessions()
        {
            lock (_lockObj)
            {
                foreach (var item in _userSessions.Where(p => DateTime.Now - p.Value.InitTime > SessionMaxTime).ToList())
                {
                    _userSessions.Remove(item.Key);
                }
            }
        }
    }
}
