using System;
using System.Threading;
using System.Collections;
using System.Reflection;

using Core.Mes.IBaseInterface;

namespace Core.Mes.ServerFrameWork
{
	/// <summary>
	/// 容器型服务的统一接口
	/// </summary>
	public class IServerPool : IServerBase
	{
		#region IServerBase 成员

		public string Description
		{
			get
			{
				// TODO:  添加 IServerPool.Description getter 实现
				return null;
			}
		}

		private Hashtable _dbManager = null;
		public Hashtable DBManagerList
		{
			get{return _dbManager;}
			set{_dbManager = value;}
		}

		private Hashtable _htComponent = new Hashtable();
		public Hashtable HtComponent
		{
			get { return _htComponent;}
			set { _htComponent = value;}
		}

		#endregion

		#region IDisposable 成员

		public void Dispose()
		{
			System.Collections.IEnumerator ie = this.HtComponent.GetEnumerator() ;

			while(ie.MoveNext())
			{
				try
				{
					System.Collections.DictionaryEntry de = (DictionaryEntry)ie.Current;
					DisposeClass((Hashtable)de.Value,0);
					DisposeClass((Hashtable)de.Value,1);
				}
				catch{}
			}
		}
		private void DisposeClass(Hashtable ht, int index)
		{
			try
			{
				ArrayList al = ht[index] as ArrayList;
				int count = al.Count ;
				for(int i = 0; i < al.Count ; i++)
				{
					try
					{
						((IComponent)al[0]).Dispose();
					}
					catch{}
				}
			}
			catch{}
		}

		

		//=======================================================
		// 加载单个类,并按最小副本数生成多个类的实例
		//	classPoolHash 0--闲列表	1-忙列表	2--最小副本数	3--最大副本数
		//=======================================================
		public void LoadClass(Type moduleType, string dataBaseName)
		{	
			try
			{
				string className = moduleType.FullName;
				//== 反射类
				IComponent module  = (IComponent)Activator.CreateInstance(moduleType);
				module.DBName = dataBaseName;
				module.DBManagerList  = this.DBManagerList;
				
				
				int maxCopyValue = module.maxValue;
				int minCopyValue = module.minValue;

				Hashtable classPoolHash = (Hashtable)HtComponent[className];

				if(classPoolHash == null)
				{
					classPoolHash = new Hashtable();
					HtComponent.Add(className, classPoolHash);
				}
			
				//存储每个类的空闲列表
                ArrayList freeList = classPoolHash[0] as ArrayList;
				if(freeList == null)
				{
					freeList = new ArrayList();
					classPoolHash.Add(0,freeList);
				}

				//存储一个空忙列表
                ArrayList busyList = classPoolHash[1] as ArrayList;
				if(busyList==null)
				{
					busyList=new ArrayList();
					classPoolHash.Add(1,busyList);
				}

				//加入最小副本数个副本到空闲列表
				freeList.Add(module);
			
				if (minCopyValue < 1) minCopyValue = 1;
				
				for(int i=0; i<minCopyValue-1; i++)
				{
					IComponent classObj = (IComponent)Activator.CreateInstance(moduleType); 
					
					classObj.DBName = dataBaseName;
					classObj.DBManagerList = this.DBManagerList;
					
					freeList.Add(classObj);
				}

				//加入最大，最小副本值
				classPoolHash.Add(2,maxCopyValue);
				classPoolHash.Add(3,minCopyValue);
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.Message);
			}
		}
		#endregion

		private string _serverName = "";
		public string ServerName
		{
			get { return _serverName; }
			set { _serverName = value; }
		}
		private string _assemblyName = "";
		public string AssemblyName
		{
			get { return _assemblyName; }
			set { _assemblyName = value; }
		}

		public ReturnObject HandleMethod(string className, string methodName, object[] args)
		{
			//查找对应的业务组件子服务
			Result structObj = this.searchObject(className);		
			
			if (structObj.busy.Equals("Error"))
			{	
				//无此所访问的类
				return new ReturnObject(null,10003,"未找到请求的类！");
			}
			else if (structObj.busy.Equals("Wait"))
			{	
				//达到最大访问限制，等待，超过规定时间放弃
				int i=1;
				while(structObj.busy.Equals("Wait"))
				{
					if ((i++)>30)
					{
						//3秒后放弃，超时返回
						return new ReturnObject(null,10001,"服务正忙，请稍后再试！");
					}
					Thread.Sleep(100);					
					structObj = this.searchObject(className);	
				}
			}

			//得到正确的副本后...
			
			//执行方法
			Type type = structObj.obj.GetType();
			MethodInfo mthod=type.GetMethod(methodName);
			object myReturnObj;

			if(mthod==null)
			{
				myReturnObj = new ReturnObject(null,10002,"未找到方法，请检查方法名是否正确！");
			}
			else
			{
				try
				{
					
                    myReturnObj = mthod.Invoke(structObj.obj,args);
				}
				catch (Exception ex)
				{
					myReturnObj = new ReturnObject(null, ex.Message);
				}
			}
			
			//释放副本
			this.realeasObject(className,structObj.obj as IComponent);
			
			if (myReturnObj.GetType().Equals(typeof(ReturnObject)))
				return (ReturnObject)myReturnObj;
			else
				return new ReturnObject(myReturnObj,10005,"未按指定的类型定义返回值！");
			
		}
		private Result searchObject(string className)
		{
			string busy="Success";
			string err="";

			Hashtable poolHash=(Hashtable)this.HtComponent[className];
				
			if(poolHash==null)
			{
				busy="Error";
				err="no the class";
				Result result=new Result(busy,err,null);
				return result;
			}
			lock(poolHash)
			{
				//取出空闲和忙列表
                ArrayList frList  = poolHash[0] as ArrayList;
                ArrayList bsyList = poolHash[1] as ArrayList;
				if(bsyList==null)
				{
					bsyList=new ArrayList();
					poolHash.Add(1,bsyList);
				}
				//如果无空闲副本，且忙列表超过最大副本数目，等待后重新请求
				//否则返回空闲副本
				if(frList.Count>0)
				{
					IComponent temp=(IComponent)frList[0];
					
					bsyList.Add(temp);
					frList.RemoveAt(0);
					Result result=new Result(busy,err,temp);
						
					return result;
				
				}
				//最大，等待
				if(bsyList.Count==Convert.ToInt16(poolHash[2]))
				{
					busy="Wait";
					Result result=new Result(busy,err,null);
					return result;
				}
				//创建并返回新副本
			
				if(bsyList.Count<Convert.ToInt16(poolHash[2]))
				{	
					Assembly ab=Assembly.Load(this.AssemblyName);
					Type tp=ab.GetType(className);
					IComponent newObj=(IComponent)Activator.CreateInstance(tp); 
					
					bsyList.Add(newObj);
					Result result=new Result(busy,err,newObj);
					return result;
				}			
				return new Result("","",null);
			}
		}
        public string realeasObject(string className, IComponent busyObj)
        {
            string err = "success";

            Hashtable poolHash = (Hashtable)this.HtComponent[className];

            if (poolHash == null)
            {
                err = "no the class";
                return err;
            }
            lock (poolHash)
            {
                //移入空闲列表
                ArrayList frList = poolHash[0] as ArrayList;
                ArrayList bsyList = poolHash[1] as ArrayList;
                //如果空闲副本数目大于最小副本数目，销毁生存期较长副本
                if (frList.Count > Convert.ToInt16(poolHash[3]))
                {
                    bsyList.Remove(busyObj);
                    busyObj.Dispose();
                    busyObj = null;
                    return err;
                }

                frList.Add(busyObj);
                bsyList.Remove(busyObj);
                return err;
            }
        }


		public struct Result
		{
			public string busy;
			public string err;
			public object  obj;
			
			public Result(string busy,string err,object obj)
			{
				this.busy=busy;
				this.err=err;
				this.obj=obj;
			}
		}
	}
}
