using CommonAI.Zone;
using CommonAI.ZoneServer;
using CommonLang.IO;
using CommonLang.Log;
using MPQ.FileSystem;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Windows.Forms;

namespace CommonAIServer.Connector
{
    public abstract class TestClientLoader
    {
        public TestClientLoader()
        {
        }

        public void Init(DirectoryInfo mpq_path)
        {
            LoadDlls();
            Resource.SetLoader(new ResourceLoader(mpq_path));
        }

        public abstract CreateUnitInfoR2B GenUnitInfoR2B(int unitID);

        public abstract Type ZoneFactoryType { get; }

        public class ResourceLoader : DefaultResourceLoader
        {
            private Logger log = LoggerFactory.GetLogger("ResourceLoader");
            private MPQFileSystem mFileSystem;

            public ResourceLoader(DirectoryInfo dir)
            {
                mFileSystem = new MPQFileSystem();
                mFileSystem.init(dir);
            }

            public override byte[] LoadData(string path)
            {
                byte[] ret = mFileSystem.getData(path);
                if (ret == null)
                {
                    ret = base.LoadData(path);
                }
                return ret;
            }

            public override bool ExistData(string path)
            {
                if (mFileSystem.findEntry(path) != null)
                {
                    return true;
                }
                return base.ExistData(path); 
            }
        }
        public static void LoadDlls()
        {
            AppDomain domain = AppDomain.CurrentDomain;

            FileInfo exefile = new FileInfo(Application.ExecutablePath);
            foreach (FileInfo file in exefile.Directory.GetFiles())
            {
                if (file.Extension.ToLower().Equals(".dll"))
                {
                    try
                    {
                        Assembly asm = Assembly.ReflectionOnlyLoadFrom(file.FullName);
                        //Assembly asm = Assembly.ReflectionOnlyLoad(File.ReadAllBytes(file.FullName));
                        if (!ExistAssembly(domain, asm.FullName))
                        {
                            domain.Load(asm.FullName);
                        }
                    }
                    catch (Exception err) { }
                }
            }
        }

        private static bool ExistAssembly(AppDomain domain, string name)
        {
            foreach (Assembly asm in domain.GetAssemblies())
            {
                if (asm.FullName.Equals(name))
                {
                    return true;
                }
            }
            return false;
        }
    }
}