using Microsoft.Practices.ServiceLocation;
using SolrNet;
using SolrNet.Commands.Parameters;
using SolrNet.Impl;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DapperORM
{
    /// <summary>
    /// solr 
    /// </summary>
    public class SolrManager
    {
        #region solr连接字符串-SolrUrl
        private static string _solrUrl;
        /// <summary>
        /// solr连接字符串
        /// </summary>
        public static string SolrUrl
        {
            get
            {
                if (string.IsNullOrEmpty(_solrUrl))
                {
                    if (ConfigurationManager.AppSettings.AllKeys.Contains("SorlUrl"))
                    {
                        _solrUrl = ConfigurationManager.AppSettings["SorlUrl"].ToString();
                    }
                }
                return _solrUrl;
            }
        }
        #endregion
        #region solr操作对象
        private static Dictionary<string, object> _Operation = new Dictionary<string, object>();
        private static readonly object lockobj = new object();
        private static ISolrOperations<T> GetOperation<T>(string corename)
        {
            if (!_Operation.ContainsKey(corename) || _Operation[corename] == null)
                return GetSolrOperations<T>(corename);
            else
                return _Operation[corename] as ISolrOperations<T>;
        }

        /// <summary>
        /// 获取SOLR操作对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="corename"></param>
        /// <returns></returns>
        private static ISolrOperations<T> GetSolrOperations<T>(string corename)
        {
            var container = Startup.Container;
            ISolrOperations<T> ioperations = null;
            lock (lockobj)
            {
                try
                {
                    var instance = container.GetInstance<ISolrOperations<T>>();
                    if (instance != null)
                        ioperations = instance;
                }
                catch (ActivationException ex)
                {
                    if (ex.InnerException.Message.Equals("给定关键字不在字典中。"))
                    {
                        Startup.Init<T>(new PostSolrConnection(SolrUrl + corename));
                        ioperations = container.GetInstance<ISolrOperations<T>>();
                    }
                    else
                        throw ex;
                }
                finally
                {
                    if (!_Operation.ContainsKey(corename))
                        _Operation.Add(corename, ioperations);
                    else
                        _Operation[corename] = ioperations;
                }
                return ioperations;
            }
        }
        #endregion
        #region solr是否可用-SolrEnabled
        private static bool _solrEnabled;
        /// <summary>
        /// solr是否可用
        /// </summary>
        public static bool SolrEnabled
        {
            get
            {
                if (!_solrEnabled)
                {
                    bool retVal;
                    _solrEnabled = bool.TryParse(ConfigurationManager.AppSettings["SolrEnabled"], out retVal) && retVal;
                }
                return _solrEnabled;
            }
        }
        #endregion

        #region 插入数据至solr

        #region 插入单条数据
        /// <summary>
        /// 插入单条数据
        /// </summary>
        /// <param name="itemList"></param>
        public static void Add<T>(T solrItem, string corename)
        {
            if (!SolrEnabled)
                return;
            GetOperation<T>(corename).Add(solrItem);
            GetOperation<T>(corename).Commit();
        }
        #endregion

        #region 批量插入
        public static void AddBatch<T>(List<T> list, string corename)
        {
            if (!SolrEnabled)
            {
                return;
            }
            GetOperation<T>(corename).AddRange(list);

            GetOperation<T>(corename).Commit();
        }
        #endregion
        #endregion

        #region 更新solr
        public static void Upsert<T>(T solrItem, string corename, bool isOverriden = false)
        {
            if (!SolrEnabled)
            {
                return;
            }

            if (solrItem == null)
            {
                return;
            }

            if (isOverriden)
            {
                GetOperation<T>(corename).Add(solrItem, new AddParameters { Overwrite = true });
            }
            else
            {
                GetOperation<T>(corename).Add(solrItem);
            }

            GetOperation<T>(corename).Commit();
        }
        #endregion
        #region 删除solr
        #region 根据Id删除
        public static void Delete<T>(string id, string corename)
        {
            if (!SolrEnabled)
            {
                return;
            }
            GetOperation<T>(corename).Delete(id);

            GetOperation<T>(corename).Commit();
        }
        #endregion
        #region 根据条件删除
        public static void Delete<T>(SolrMultipleCriteriaQuery query, string corename)
        {
            if (!SolrEnabled)
            {
                return;
            }
            GetOperation<T>(corename).Delete(query);

            GetOperation<T>(corename).Commit();
        }
        #endregion

        #endregion
        #region 查询
        public static SolrQueryResults<T> Query<T>(string corename, int pageIndex, int pageSize, SolrMultipleCriteriaQuery query, List<SortOrder> sort, List<ISolrFacetQuery> facet)
        {
            if (!SolrEnabled)
            {
                return null;
            }

            var start = (pageIndex - 1 < 0 ? 0 : pageIndex - 1) * pageSize;

            var results = GetOperation<T>(corename).Query(query, new QueryOptions
            {
                OrderBy = sort,
                Facet = new FacetParameters
                {
                    Queries = facet
                },
                Start = start,
                Rows = pageSize
            });

            //var count = results.NumFound;

            return results;
        }
        #endregion
    }
}
