using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.Text;
using System.Reflection;
using QMAPP.BLL;
using QMFrameWork.ServiceInterface;

namespace QMFrameWork.WebServiceHost
{
    /// <summary>
    /// 服务工厂
    /// </summary>
    public class ServiceFactory
    {
        private static Hashtable ServiceList = null;

        /// <summary>
        /// 业务库存储路径
        /// </summary>
        public static string BusinessDllPath { get; set; }

        #region 获取服务列表

        /// <summary>
        /// 获取服务列表
        /// </summary>
        /// <returns>服务列表</returns>
        public static List<string> GetServiceList()
        {
            List<string> list = new List<string>();

            try
            {
                foreach (string key in ServiceList.Keys)
                {
                    list.Add(key);
                }

                return list;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        #endregion

        #region 加载配置信息

        /// <summary>
        /// 加载配置信息
        /// </summary>
        public static void Configure()
        {
            if (ServiceList != null)
                return;

            try
            {
                string file = System.Web.HttpContext.Current.Server.MapPath("~/App_Data/BusinessDllList.xml");

                BusinessDllPath = System.Web.HttpContext.Current.Server.MapPath("~/Bin/");

                ServiceList = new Hashtable();

                XElement xel = XElement.Load(file);

                var datas = from x in xel.Descendants("ServiceDefinition")
                            select x;

                foreach (XElement d in datas)
                {
                    //定义服务
                    ServiceDefinition service = new ServiceDefinition();
                    service.ServiceName = d.Element("ServiceName").Value;
                    service.FullLogicClassName = d.Element("FullLogicClassName").Value;
                    service.AssemblyFile = BusinessDllPath + d.Element("AssemblyFile").Value;

                    if (d.Element("IsCredential") != null)
                    {
                        service.IsCredential = bool.Parse(d.Element("IsCredential").Value);
                    }
                    else
                    {
                        service.IsCredential = true;
                    }

                    ServiceList.Add(service.ServiceName, service);

                    //定义方法
                    //service.Functions = new List<ServiceFunctionDefinition>();
                    //service.Functions.Add(new ServiceFunctionDefinition { RequestFunctionName = "GetList", ClassFunctionName="GetList" });
                }
            }
            catch (Exception ex)
            {
                throw new Exception("加载服务配置信息出现问题!- " + ex.Message);
            }

        }

        #endregion

        #region 创建服务方法

        /// <summary>
        /// 创建服务方法
        /// </summary>
        /// <param name="request">服务请求</param>
        /// <param name="serviceClass">服务类</param>
        /// <returns>服务方法</returns>
        public static MethodInfo CreateServiceFunction(ServiceRequest request, ref object serviceClass)
        {
            MethodInfo method = null;
            string[] requestValues = request.FunctionName.Split("_".ToArray());
            string serviceName = requestValues[0];
            string requestFunctionName = requestValues[1];

            if (ServiceList.ContainsKey(serviceName) == true)
            {
                ServiceDefinition service = ServiceList[serviceName] as ServiceDefinition;

                if (service.IsCredential == true && request.UserCredential == null)
                {
                    throw new Exception("没有指定用户凭据。");
                }

                string functionName = requestFunctionName;

                if (service.Functions != null && service.Functions.Count > 0)
                {
                    ServiceFunctionDefinition classFunction = service.Functions.Find(p => p.RequestFunctionName == requestFunctionName);

                    if (classFunction == null)
                    {
                        throw new Exception("请求的方法不存在!");
                    }

                    functionName = classFunction.ClassFunctionName;
                }

                Assembly Asse = Assembly.LoadFrom(service.AssemblyFile);
                serviceClass = Asse.CreateInstance(service.FullLogicClassName);

                (serviceClass as BaseBLL).LoginUser = new QMAPP.Model.Sys.LoginInfo { UserID = request.UserCredential.UserID };

                method = serviceClass.GetType().GetMethod(functionName);
            }
            else
            {
                throw new Exception("请求的服务不存在或没有继承逻辑层基类!");
            }


            return method;
        }

        #endregion
    }
}