using System;
using System.Collections.Generic;
using System.Reflection;
using System.Configuration;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using System.Diagnostics;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Configuration;
using System.ServiceModel.Description;


namespace SiaSun.LMS.WinService
{
    public class ServiceHostGroup
    {
        public static List<ServiceHost> _hosts = new List<ServiceHost>();
        
        /// <summary>
        /// ¿ªÊ¼·þÎñ
        /// </summary>
        private static void OpenHost(Type t, string iType, string url, string binding)
        {
            ServiceHost hst = new ServiceHost(t, new Uri(string.Format(url,Program._BaseUrl )));
            ServiceThrottlingBehavior throttlingBehavior = hst.Description.Behaviors.Find<ServiceThrottlingBehavior>();
            if (throttlingBehavior == null)
            {
                throttlingBehavior = new ServiceThrottlingBehavior { MaxConcurrentCalls = 3000, MaxConcurrentSessions = 3000 };
                hst.Description.Behaviors.Add(throttlingBehavior);
            }
            else
            {
                throttlingBehavior.MaxConcurrentCalls = 3000;
                throttlingBehavior.MaxConcurrentSessions = 3000;
            }

            ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
            smb.HttpGetEnabled = true;
            hst.Description.Behaviors.Add(smb);

            hst.AddServiceEndpoint(iType, SiaSun.LMS.Common.WCFHelper.CreateBinding(binding), "");
            hst.Open();
            _hosts.Add(hst);
        }

        /// <summary>
        /// Æô¶¯ËùÓÐÅäÖÃÎļþÖеķþÎñ
        /// </summary>
        public static void StartAllConfiguredServices()
        {
            ConfiguredServices services = ConfiguredServices.LoadFromFile("services.xml");

            foreach (ConfiguredService svc in services.Services)
            {
                Type svcType = Type.GetType(svc.Type);

                string svcIType = svc.iType;

                string binding = svc.binding;

                string url = svc.URL;

                if (svcType == null) throw new Exception("ÅäÖÃÎļþÖеķþÎñÀàÐÍ " + svc.Type + "ÎÞЧ");

                OpenHost(svcType, svcIType, url, binding);
            }
        }

        /// <summary>
        /// ¹Ø±ÕËùÓзþÎñ
        /// </summary>
        public static void CloseAllServices()
        {
            foreach (ServiceHost hst in _hosts)
            {
                hst.Close();
            }
        }
    }

    [XmlRoot("configuredServices")]
    public class ConfiguredServices
    {
        public static ConfiguredServices LoadFromFile(string filename)
        {
            if (!File.Exists(AppDomain.CurrentDomain.BaseDirectory + filename)) return new ConfiguredServices();

            XmlSerializer ser = new XmlSerializer(typeof(ConfiguredServices));

            using (FileStream fs = File.OpenRead(AppDomain.CurrentDomain.BaseDirectory + filename))
            {
                return (ConfiguredServices)ser.Deserialize(fs);
            }
        }

        [XmlElement("service", typeof(ConfiguredService))]
        public List<ConfiguredService> Services = new List<ConfiguredService>();
    }

    public class ConfiguredService
    {
        [XmlAttribute("type")]
        public string Type;

        [XmlAttribute("itype")]
        public string iType;

        [XmlAttribute("binding")]
        public string binding;

        [XmlAttribute("url")]
        public string URL;
    }
}