using Long.Core.Extensions;
using System.Runtime.Caching;

namespace Long.Utils.Cache
{
    /// <summary>
    /// 缓存类
    /// </summary>
    public class ObjectCaching
    {
        /// <summary>
        /// 添加缓存
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="value">值</param>
        /// <param name="timeout">过期时间（秒）</param>
        public static void Add(string key, object value, long timeout = 60)
        {
            Add(key, value, timeout, null);
        }

        /// <summary>
        /// 添加缓存
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="value">值</param>
        /// <param name="timeout">过期时间（秒）</param>
        /// <param name="regionName">区域名称</param>
        /// <exception cref="ApplicationException"></exception>
        public static void Add(string key, object value, long timeout, string regionName)
        {
            ObjectCache cache = MemoryCache.Default;
            key.AssertNullOrWhiteSpace("缓存键名不能未空。");
            if (timeout <= 0)
            {
                throw new ApplicationException("参数 timeout 的值不能小于1。");
            }
            var policy = new CacheItemPolicy()
            {
                SlidingExpiration = new TimeSpan(timeout * TimeSpan.TicksPerSecond),
            };
            cache.Add(key, value, policy, regionName);
        }

        /// <summary>
        /// 判断缓存内容是否存在
        /// </summary>
        /// <param name="key">键</param>
        /// <returns></returns>
        public static bool Contains(string key)
        {
            return Contains(key, null);
        }

        /// <summary>
        /// 判断缓存内容是否存在
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="regionName">区域名</param>
        /// <returns></returns>
        public static bool Contains(string key, string regionName)
        {
            ObjectCache cache = MemoryCache.Default;
            key.AssertNullOrWhiteSpace("缓存键名不能未空。");
            return cache.Contains(key, regionName);
        }

        /// <summary>
        /// 获取缓存内容
        /// </summary>
        /// <typeparam name="T">泛型对象</typeparam>
        /// <param name="key">键</param>
        /// <returns></returns>
        public static T Get<T>(string key)
        {
            ObjectCache cache = MemoryCache.Default;
            key.AssertNullOrWhiteSpace("缓存键名不能未空。");
            return (T)cache.Get(key, null);
        }

        /// <summary>
        /// 获取缓存内容
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="regionName">区域名</param>
        /// <returns></returns>
        public static T Get<T>(string key, string regionName)
        {
            ObjectCache cache = MemoryCache.Default;
            key.AssertNullOrWhiteSpace("缓存键名不能未空。");
            return (T)cache.Get(key, regionName);
        }

        /// <summary>
        /// 删除缓存
        /// </summary>
        /// <param name="key"></param>
        public static void Remove(string key)
        {
            Remove(key, null);
        }

        /// <summary>
        /// 删除缓存
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="regionName">区域名</param>
        public static void Remove(string key, string regionName)
        {
            ObjectCache cache = MemoryCache.Default;
            key.AssertNullOrWhiteSpace("缓存键名不能未空。");
            cache.Remove(key, regionName);
        }
    }
}
