/* ==============================================================================
 * 功能描述:RevitCoreContext  
 * 创 建 者:Garrett
 * 创建日期:2019/6/27 11:10:20
 * ==============================================================================*/
using Autodesk.Revit;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.DB;
using SAGA.DotNetUtils.Revit;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;

namespace ExportStart
{
    public class RevitCoreContext
    {
        // 此路径为动态反射搜索路径 、 此路径可为任意路径(只要路径下有RevitNET 所需依赖项即可,完整依赖项可在 Naviswork 2016 下面找到)

        private static readonly string[] Searchs = RevitUtils.GetSearchPath().ToArray();

        static readonly object lockobj = new object();

        static RevitCoreContext _instance;

        private Product _product;

        public Application Application { get => _product.Application; }

        public static RevitCoreContext Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (lockobj)
                    {
                        if (_instance == null)
                        {
                            _instance = new RevitCoreContext();
                        }
                    }
                }

                return _instance;
            }
        }

        static RevitCoreContext()
        {
            AddEnvironmentPaths(Searchs);

            AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;
        }

        public void Run()
        {
            _product = Product.GetInstalledProduct();

            var clientId = new ClientApplicationId(Guid.NewGuid(), "DotNet", "BIMAPI");

            // I am authorized by Autodesk to use this UI-less functionality. 必须是此字符串。 Autodesk 规定的.

            _product.Init(clientId, "I am authorized by Autodesk to use this UI-less functionality.");
        }

        public void Stop()
        {
            _product?.Exit();
        }

        static void AddEnvironmentPaths(params string[] paths)
        {
            var path = new[] { Environment.GetEnvironmentVariable("PATH") ?? string.Empty };
            //加在最前面,
            var newPath = string.Join(System.IO.Path.PathSeparator.ToString(), paths.Concat(path));

            Environment.SetEnvironmentVariable("PATH", newPath);
        }

        private static Assembly OnAssemblyResolve(object sender, ResolveEventArgs args)
        {
            var assemblyName = new AssemblyName(args.Name);
            //File.AppendAllText(@"E:\startlog.txt","args:"+ args.Name + "\r\n");
            foreach (var item in Searchs)
            {
                var file = string.Format("{0}.dll", System.IO.Path.Combine(item, assemblyName.Name));

                if (File.Exists(file))
                {
                    AddAssemblys(assemblyName.Name);
                    //File.Copy(file,Path.Combine(@"D:\Revit\RevitExport\JBIM\OutputDll\2018",assemblyName.Name+".dll"),true);

                    return Assembly.LoadFile(file);
                }
            }

            return args.RequestingAssembly;
        }
        public static List<string> NeedAssemblys = new List<string>();

        public static void AddAssemblys(string str)
        {
            if(!NeedAssemblys.Contains(str))
                NeedAssemblys.Add(str);
        }

    }
}