using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Foresight.Cache;
using Foresight.Cache.AspNet;
using Foresight.Cache.Redis;

namespace IronIntel.Contractor
{
    public static class CacheManager
    {
        public static void Dispose()
        {
            if (_Client != null)
            {
                _Client.Dispose();
                _Client = null;
            }
        }

        private static CacheClient _Client = null;
        private static object _sycobj = new object();

        private static FIRedisCacheClient CreateRedisClient(string[] servers)
        {
            if ((servers == null) || (servers.Length == 0))
            {
                return null;
            }
            List<RedisNode> ls = new List<RedisNode>();
            foreach (string srv in servers)
            {
                try
                {
                    RedisNode node = CreateRedisNode(srv);
                    ls.Add(node);
                }
                catch (Exception ex)
                {
                    ContractorHost.Instance.WriteLog("Error", typeof(CacheManager).FullName + ".CreateRedisClient", "Create RedisNode failed: " + srv, ex.ToString(), string.Empty);
                }
            }
            if (ls.Count == 0)
            {
                return null;
            }
            else
            {
                return new FIRedisCacheClient("IRONINTEL_" + ContractorHost.Instance.CustomerID.ToUpper(), ls);
            }
        }

        private static RedisNode CreateRedisNode(string server)
        {
            string[] address = server.Split(new char[] { ':' });
            int port = -1;
            if (!int.TryParse(address[1], out port))
            {
                port = -1;
            }
            int weight = 100;
            if (!int.TryParse(address[2], out weight))
            {
                weight = 100;
            }
            RedisNode node = new RedisNode(address[0], port, weight);
            return node;
        }

        private static void InitCacheClient()
        {
            FIRedisCacheClient fc = null;
            try
            {
                fc = CreateRedisClient(ContractorHost.Instance.RedisServersAddress);
            }
            catch (Exception ex)
            {
                ContractorHost.Instance.WriteLog("Error", typeof(CacheManager).FullName + ".InitCacheClient", "Create Redis client failed", ex.ToString(),string.Empty);
            }
            if (fc != null)
            {
                _Client = fc;
                return;
            }
            else
            {
                _Client = new AspNetCacheManager("IRONINTEL_" + ContractorHost.Instance.CustomerID.ToUpper());
            }
        }

        private static CacheClient Client
        {
            get
            {
                if (_Client == null)
                {
                    lock (_sycobj)
                    {
                        if (_Client == null)
                        {
                            InitCacheClient();
                        }
                    }
                }
                return _Client;
            }
        }

        public static void Remove(string key)
        {
            if (Client != null)
            {
                try
                {
                    Client.Remove(key);
                }
                catch
                { }
            }
        }

        public static void SetValue(string key, byte[] buffer, TimeSpan expire)
        {
            if (buffer == null)
            {
                Remove(key);
            }
            else if (Client != null)
            {
                try
                {
                    Client.SetValue(key, buffer, expire);
                }
                catch
                { }
            }
        }

        public static byte[] GetValue(string key)
        {
            if (Client != null)
            {
                try
                {
                    return Client.GetValue(key);
                }
                catch
                {
                    return null;
                }
            }
            else
            {
                return null;
            }
        }
    }
}