using System;
using System.Text;
using Falcon.Extend;
using Microsoft.Extensions.Logging;

namespace StaffManagement.Extensions
{
    /// <summary>
    /// 缓冲帮助器
    /// </summary>
    public class CacheHelper
    {
        /// <summary>
        /// 基础缓冲
        /// </summary>
        public ICacheProvider Cache { get; set; }
        /// <summary>
        /// Json序列化
        /// </summary>
        public IJsonProvider JsonProvider { get; set; }
        /// <summary>
        /// 日志记录
        /// </summary>
        public ILogger Logger { get; set; }

        public CacheHelper(ICacheProvider c,IJsonProvider j,ILogger<CacheHelper> logger) {
            this.Cache = c;
            this.JsonProvider = j;
            this.Logger = logger;
        }
        /// <summary>
        /// 从缓冲中获取数据
        /// </summary>
        /// <typeparam name="TKey">用于生成key的对象类型</typeparam>
        /// <typeparam name="T">数据对象类型</typeparam>
        /// <param name="prefix">缓冲方法前缀</param>
        /// <param name="keyObj">用于生成key的对象</param>
        /// <returns>数据对象</returns>
        public T GetT<TKey, T>(string prefix,TKey keyObj) where T : class, new() {
            if(this.Cache == null) {
                return null;
            }
            if(this.JsonProvider == null) {
                return null;
            }
            var key = generateKey(prefix,keyObj);
            if(string.IsNullOrEmpty(key)) {
                return null;
            }
            var result = this.Cache.GetObj<T>(key);
            if(result != null) {
                this.Logger.LogInformation($"Get data cache by [{key}]");
            }
            return result;
        }
        /// <summary>
        /// 保存缓冲
        /// </summary>
        /// <typeparam name="TKey">用于生成key的对象类型</typeparam>
        /// <typeparam name="T">数据对象类型</typeparam>
        /// <param name="prefix">缓冲方法前缀</param>
        /// <param name="keyObj">用于生成key的对象</param>
        /// <param name="obj">数据对象</param>
        /// <param name="timeSpan">缓冲时间</param>
        /// <returns></returns>
        public T SetT<TKey, T>(string prefix,TKey keyObj,T obj,TimeSpan timeSpan) where T : class {
            if(this.Cache == null) {
                return obj;
            }
            if(this.JsonProvider == null) {
                return obj;
            }
            var key = generateKey(prefix,keyObj);
            if(string.IsNullOrEmpty(key)) {
                return obj;
            }
            this.Cache.SetCache(key,obj,timeSpan);
            this.Logger.LogInformation($"Set data cache by [{key}]");
            return obj;
        }
        /// <summary>
        /// 根据对象生成Key
        /// </summary>
        /// <typeparam name="TK">Key的类型</typeparam>
        /// <param name="prefix">前缀</param>
        /// <param name="keyObj">Key对象</param>
        /// <returns>对应的Key字符串</returns>
        private string generateKey<TK>(string prefix,TK keyObj) {
            var key = new StringBuilder();
            key.Append(prefix);
            foreach(var p in keyObj.GetType().GetProperties()) {
                var pn = p.Name;
                var pv = p.GetValue(keyObj) ?? "nul";
                key.Append($":{pn}:{pv}");
            }
            return key.ToString();
        }
    }
}
