using System.Diagnostics;
using System.Reflection;

namespace Updater;

public class Program 
{
    public static string Slash
    {
        get
        {
            if (OperatingSystem.IsWindows()) return "\\";
            else return "/";
        }
    }
    
    public static string JT
    {
        get
        {
            string tmp = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "JacobTech");
            if (OperatingSystem.IsLinux())
            {
                tmp = Path.Combine(Environment.GetEnvironmentVariable("HOME")!, ".config/");
                tmp += "JacobTech";
            }
            return tmp;
        }
    }
    public static string[] rawargs;
    public static bool NewUpdater = false;
    private static string? del = null;
    public const string Domain = "www.JacobTech.com";
    internal static Argumets Argumets { get; } = new();

    [STAThread]
    public static int Main(string[] args)
    {
        try
        {
    #if DEBUG
            args = new string[] { "--process", "vyukgykgyh", "--remotedirectory", "Luski", "--localdirectory",  $"/home/jacob/Documents/Updater/Updater/bin/Release/ttt", "--dll", "Luski", "--selfcontained", "false", "--branch", "Dev", "--platform", "linux-x64" };
            string bbbbbb = $"\"{string.Join("\" \"", args)}\"";
    #endif
            rawargs = args;
            int skip = 0;
            if (args.Length > 2)
            {
                for (int i = 0; i < args.Length; i++)
                {
                    if (args[i].StartsWith("--"))
                    {
                        if (((args.Length - 1) >= (i + 1)))
                        {
                            switch (args[i].Remove(0, 2).ToLower())
                            {
                                case "updater":
                                    skip++;
                                    NewUpdater = true;
                                    Argumets.Updater = args[i + 1];
                                    break;
                                case "setconfig":
                                    skip++;
                                    Argumets.Loc = args[i + 1];
                                    break;
                                case "process":
                                    skip++;
                                    Argumets.Process = args[i + 1];
                                    break;
                                case "remotedirectory":
                                    skip++;
                                    Argumets.RemoteDirectory = args[i + 1];
                                    break;
                                case "branch":
                                    skip++;
                                    Argumets.Branch = args[i + 1];
                                    break;
                                case "localdirectory":
                                    skip++;
                                    Argumets.LocalDirectory = args[i + 1];
                                    break;
                                case "dll":
                                    skip++;
                                    Argumets.DLL = args[i + 1];
                                    break;
                                case "version":
                                    skip++;
                                    Argumets.Version = args[i + 1];
                                    break;
                                case "selfcontained":
                                    skip++;
                                    Argumets.SeflContaind = bool.Parse(args[i + 1]);
                                    break;
                                case "platform":
                                    skip++;
                                    Argumets.Platform = args[i + 1];
                                    break;
                            }
                            i++;
                        }
                        else
                        {
                            Console.WriteLine($"Argument {args[i].Remove(0, 2)} had no value");
                            return 1;
                        }
                    }
                    
                }
                if (!Argumets.Verify())
                {
                    Console.WriteLine("Not enough arguments were given");
                    return 1;
                }
                skip *= 2;
                Argumets.args = args.Skip(skip).ToList();
                if (FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion != new HttpClient().GetAsync($"https://www.jacobtech.com/Updater/GetProgramVersion?directory=Updater{Argumets.UriPlatform}{Argumets.UriSeflContaind}").Result.Content.ReadAsStringAsync().Result)
                {
                    //todo this is broken
                    if (Argumets.Updater is not null)
                    {
                        StartGUI.Main(Argumets);
                    }
                    string newdir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
                    void MoveDir(string Base, string Move)
                    {
                        if (!Directory.Exists(Move)) Directory.CreateDirectory(Move);
                        DirectoryInfo di = new(Base);
                        foreach (FileInfo file in di.GetFiles())
                        {
                            file.CopyTo(Path.Combine(Move, file.Name));
                        }

                        foreach (DirectoryInfo dir in di.GetDirectories())
                        {
                            MoveDir(dir.FullName, Path.Combine(Move, dir.Name));
                            Directory.Delete(dir.FullName);
                        }
                    }
                    MoveDir(AppDomain.CurrentDomain.BaseDirectory, newdir);
                    Process p = new();
                    p.StartInfo.FileName = Path.Combine(newdir, AppDomain.CurrentDomain.FriendlyName);
                    if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS() || OperatingSystem.IsFreeBSD())
                    {
                        Process m = Process.Start("/usr/bin/chmod", $"+x {Path.Combine(newdir, AppDomain.CurrentDomain.FriendlyName)}");
                        m.WaitForExit();
                    }

                    p.StartInfo.WorkingDirectory = newdir;
                    p.StartInfo.CreateNoWindow = true;
                    p.StartInfo.Arguments = $" --updater \"{AppDomain.CurrentDomain.BaseDirectory}\" \"{string.Join("\" \"", args)}\"";
                    p.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
                
                    p.Start();
                    return 0;
                }
                if (Argumets.Updater is not null)
                {
                    Directory.Delete(Argumets.Updater, true);
                    Argumets.Updater = null;
                }
                if (!Directory.Exists(JT)) Directory.CreateDirectory(JT);
                if (!Directory.Exists(Path.Combine(JT + "Updater"))) Directory.CreateDirectory(Path.Combine(JT + "Updater"));
                if (!Directory.Exists(Path.Combine(JT + $"Updater{Program.Slash}Config"))) Directory.CreateDirectory(Path.Combine(JT + $"Updater{Program.Slash}Config"));
                _ = Config.MakeFile();
                //return 0;
                return StartGUI.Main(Argumets);
            }
            else
            {
                 _ = MessageBox.Show("Not nough arguments were given");
                Console.WriteLine("Not nough arguments were given");
                return 1;
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            return 1;
        }
    }

    public static bool IsProcessOpen(string name)
    {
        if (!NewUpdater)
        {
            bool @out = false;
            foreach (Process clsProcess in Process.GetProcessesByName(name.ToLower()))
            {
                if (clsProcess.ProcessName.ToLower().Contains(name.ToLower()))
                {
                    @out = true;
                }
            }
            return @out;
        }
        else
        {
            if (!IsUpdaterProcessOpen())
            {
                if (del != null)
                {
                    try
                    {
                        if (Directory.Exists(del)) Directory.Delete(del, true);
                        del = null;
                    }
                    catch
                    {
                    }
                }
                bool @out = false;
                foreach (Process clsProcess in Process.GetProcessesByName(name.ToLower()))
                {
                    if (clsProcess.ProcessName.ToLower().Contains(name.ToLower()))
                    {
                        @out = true;
                    }
                }
                return @out;
            }
            else
            {
                return false;
            }
        }
    }

    public static bool IsUpdaterProcessOpen()
    {
        if (Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length <= 1)
        {
            return false;
        }
        return true;
    }
}