using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Configuration;
using RestSharp;
using Newtonsoft.Json;
//using DLLInjection;

namespace TISP_Injector
{
    class Program
    {
        static string GetCurrentVersion(bool makeNewId, out string id)
        {
            var definition = new { result = "", version = "", id = ""  };
            string url = "https://7d1odhf1jh.execute-api.us-east-1.amazonaws.com/prod/v1/checkver?newId=";
            if (makeNewId)
                url += "true";
            else
                url += "false";

            var client = new RestClient(url);
            var request = new RestRequest(Method.GET);
            request.AddHeader("TISP_Injector", "v001");
            IRestResponse response = client.Execute(request);
            var jsonResponse = JsonConvert.DeserializeAnonymousType(response.Content, definition);
            int version = 0;
            id = "";
            //string stringVersion = jsonResponse.version.Replace(".", "");
            //int.TryParse(stringVersion, out version);
            if (makeNewId)
                id = jsonResponse.id;

            return jsonResponse.version;
        }
        static void Main(string[] args)
        {
            var settings = ConfigurationManager.AppSettings;

            string TargetProcessName = "TheIsleServer-Win64-Shipping";
            TargetProcessName = settings["TargetProcess"];

            var currentDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            bool createId = false;
            var idTextPath = currentDirectory + "\\id.txt";
            if(!File.Exists(idTextPath))
            {
                Console.WriteLine("id.txt is missing, will request a new id");
                createId = true;
            }
            else
            {
                string id = File.ReadAllText(idTextPath);
                if (id.Length < 1)
                {
                    Console.WriteLine("id.txt is empty, will request a new id");
                    createId = true;
                }
            }
            string newid = "";

            string mostRecentVersion = GetCurrentVersion(createId, out newid);

            if (createId && newid != "")
            {
                File.WriteAllText(idTextPath, newid);
            }

            string dllPath = currentDirectory + "\\" + settings["Dll"];
            bool needsUpated = true;
            if(!File.Exists(dllPath))
            {
                Console.WriteLine("DLL does not exist in folder, will download.");
                needsUpated = true;
            }
            else
            {
                FileVersionInfo myFileVersionInfo = FileVersionInfo.GetVersionInfo(dllPath);
                if (myFileVersionInfo == null || myFileVersionInfo.FileVersion == null)
                {
                    needsUpated = true;
                }
                else
                {
                    try
                    {
                        if (int.Parse(myFileVersionInfo.FileVersion.Replace(".","")) >= int.Parse(mostRecentVersion.Replace(".", "")))
                        {
                            needsUpated = false;
                        }
                    }
                    catch( Exception e)
                    {
                        needsUpated = true;
                    }                    
                }
            }

            if (needsUpated)
            {
                if (settings["AutoUpdate"] == "true")
                {
                    string downloadUrl = "https://s3.amazonaws.com/tisp-versions/" + mostRecentVersion + "/TIServerPlus.dll";
                    using (var writer = File.OpenWrite(dllPath))
                    {
                        var downloadClient = new RestClient(downloadUrl);
                        var request = new RestRequest(downloadUrl);
                        request.ResponseWriter = (responseStream) => responseStream.CopyTo(writer);
                        Console.WriteLine("Downloading update...");
                        var response = downloadClient.DownloadData(request);
                        Console.WriteLine("Download complete!");
                    }
                }
                else
                {
                    Console.WriteLine("An update is available! Enable AutoUpdate to download it.");
                }
            }
            else
            {
                Console.WriteLine("Version is up to date: " + mostRecentVersion);
            }
            

            bool doWait = false;
            if (args.Length > 0)
            {
                dllPath = args[0];
            }
            if (!File.Exists(dllPath))
            {
                Console.WriteLine("DLL does not exist in folder and none was passed as a parameter!");
                Thread.Sleep(2000);
                return;
            }


            Process[] localByName = Process.GetProcessesByName(TargetProcessName);

            Console.WriteLine("Waiting for " + TargetProcessName);

            while (localByName.Length == 0)
            {
                doWait = true;
                localByName = Process.GetProcessesByName(TargetProcessName);
            }
            if (true || doWait)
            {
                int waittime = 10000;
                int.TryParse(settings["WaitTime"], out waittime);
                Console.WriteLine("Waiting " + (waittime / 1000) + " seconds before injecting...");
                Thread.Sleep(waittime);
            }

            try
            {
                var injector = new DLLInjection.DLLInjector(DLLInjection.InjectionMethod.CREATE_REMOTE_THREAD);
                injector.Inject(localByName[0].Id, dllPath);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Coulden't inject " + dllPath + " into " + localByName[0].Id);
                Thread.Sleep(2000);
                return;
            }

            Console.WriteLine("Injection successfull");
            Thread.Sleep(2000);
        }
    }
}
