#if DEBUG
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using TweetDuck.Browser;
using TweetDuck.Management;
using TweetLib.Core.Features.Plugins;

namespace TweetDuck.Resources{
    sealed class ScriptLoaderDebug : ScriptLoader{
        private static readonly string HotSwapProjectRoot = FixPathSlash(Path.GetFullPath(Path.Combine(Program.ProgramPath, "../../../")));
        private static readonly string HotSwapTargetDir = FixPathSlash(Path.Combine(HotSwapProjectRoot, "bin", "tmp"));
        private static readonly string HotSwapRebuildScript = Path.Combine(HotSwapProjectRoot, "bld", "post_build.exe");
        
        private static string FixPathSlash(string path){
            return path.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) + '\\';
        }

        public ScriptLoaderDebug(){
            if (File.Exists(HotSwapRebuildScript)){
                Debug.WriteLine("Activating resource hot swap...");

                ResetHotSwap();
                System.Windows.Forms.Application.ApplicationExit += (sender, args) => ResetHotSwap();
            }
        }

        public override void OnReloadTriggered(){
            HotSwap();
        }

        protected override string LocateFile(string path){
            if (Directory.Exists(HotSwapTargetDir)){
                Debug.WriteLine($"Hot swap active, redirecting {path}");
                return Path.Combine(HotSwapTargetDir, "scripts", path);
            }

            return base.LocateFile(path);
        }

        private void HotSwap(){
            if (!File.Exists(HotSwapRebuildScript)){
                Debug.WriteLine($"Failed resource hot swap, missing rebuild script: {HotSwapRebuildScript}");
                return;
            }
            
            ResetHotSwap();
            Directory.CreateDirectory(HotSwapTargetDir);

            Stopwatch sw = Stopwatch.StartNew();

            using(Process process = Process.Start(new ProcessStartInfo{
                FileName = HotSwapRebuildScript,
                Arguments = $"\"{HotSwapTargetDir}\\\" \"{HotSwapProjectRoot}\\\" \"Debug\" \"{Program.VersionTag}\"",
                WindowStyle = ProcessWindowStyle.Hidden
            })){
                // ReSharper disable once PossibleNullReferenceException
                if (!process.WaitForExit(8000)){
                    Debug.WriteLine("Failed resource hot swap, script did not finish in time");
                    return;
                }
                else if (process.ExitCode != 0){
                    Debug.WriteLine($"Failed resource hot swap, script exited with code {process.ExitCode}");
                    return;
                }
            }

            sw.Stop();
            Debug.WriteLine($"Finished rebuild script in {sw.ElapsedMilliseconds} ms");

            ClearCache();

            // Force update plugin manager setup scripts

            string newPluginRoot = Path.Combine(HotSwapTargetDir, "plugins");
            
            const BindingFlags flagsInstance = BindingFlags.Instance | BindingFlags.NonPublic;

            Type typePluginManager = typeof(PluginManager);
            Type typeFormBrowser = typeof(FormBrowser);

            // ReSharper disable PossibleNullReferenceException
            object instPluginManager = typeFormBrowser.GetField("plugins", flagsInstance).GetValue(FormManager.TryFind<FormBrowser>());
            typePluginManager.GetField("pluginFolder", flagsInstance).SetValue(instPluginManager, newPluginRoot);

            Debug.WriteLine("Reloading hot swapped plugins...");
            ((PluginManager)instPluginManager).Reload();
            // ReSharper restore PossibleNullReferenceException
        }

        private void ResetHotSwap(){
            try{
                Directory.Delete(HotSwapTargetDir, true);
            }catch(DirectoryNotFoundException){}
        }
    }
}

#endif