using   Microsoft.
Win32;
using   Newtonsoft.Json;
using   System;
using   System.Collections.Generic;
using   System.Diagnostics;
using   System.Globalization;
using   System.IO;
using   System.IO.Compression;
using   System.Linq;
using   System.Net.Http;
using   System.Net.Security;
using   System.Security.Cryptography.X509Certificates;
using   System.Text.Json;
using   System.Threading.Tasks;
using   System.Windows;
#nullable disable
namespace Bootstrapper
{
  internal class Installer
  {
    private readonly double currentInstallerVersion = 2.18;
    private readonly string[] solara_endpoints = new string[4]
    {
      "https://getsolara.dev/api/endpoint.json",
      "https://api.getsolara.gg/api/endpoint.json",
      "https://pastebin.com/raw/h8GnGH0Y",
"https://gitlab.com/cmd-softworks1/a/-/snippets/4768754/raw/main/endpoint.json"
    };
    private string current;
    public string BootstrapperVersion { get; private set; }
    public string SupportedClient { get; private set; }
    public string SoftwareVersion { get; private set; }
    public string BootstrapperUrl { get; private set; }
    public string SoftwareUrl { get; private set; }
    public string VersionUrl { get; private set; }
    public string ClientHash { get; private set; }
    public string Changelog { get; private set; }
    public static bool WebViewIsInstalled()
    {
      using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey("Software\\
WOW6432Node\\Microsoft\\EdgeUpdate\\Clients\\{F3017226-FE2A-4295-8BDF-
00C3A9A7E4C5}"))
        return registryKey != null && registryKey.GetValue("pv") != null;
    }
    private async Task DownloadAndStartNewBootstrapper(double newVersion)
    {
      try
      {
        string newFileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
string.Format("Bootstrapper_v{0}.exe", (object) newVersion));
        using (HttpClient httpClient = new HttpClient((HttpMessageHandler) new
HttpClientHandler()
        {
          PreAuthenticate = true,
          ServerCertificateCustomValidationCallback = (Func<HttpRequestMessage,
X509Certificate2, X509Chain, SslPolicyErrors, bool>) ((message, cert, chain,
errors) => true)
        }))
        {
          HttpResponseMessage async = await
httpClient.GetAsync(this.BootstrapperUrl);
          async.EnsureSuccessStatusCode();
          using (FileStream fs = new FileStream(newFileName, FileMode.Create,
FileAccess.Write, FileShare.None))
            await async.Content.CopyToAsync((Stream) fs);
        }
        Process process = await Task.Run<Process>((Func<Process>) (() =>
Process.Start(newFileName, Process.GetCurrentProcess().ProcessName)));
        await Task.Delay(500);
        Application.Current.Shutdown();
      }
      catch (Exception ex)
      {
        int num = (int) MessageBox.Show("An error occurred while updating the
bootstrapper:\n" + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Hand);
      }
    }
    public async Task DownloadSolara(string folderPath)
    {
      try
      {
        string parentDirectory = Directory.GetParent(folderPath).FullName;
        string tempZipPath = Path.Combine(parentDirectory, "SolaraTemp.zip");
        using (HttpClient httpClient = new HttpClient((HttpMessageHandler) new
HttpClientHandler()
        {
          PreAuthenticate = true,
          ServerCertificateCustomValidationCallback = (Func<HttpRequestMessage,
X509Certificate2, X509Chain, SslPolicyErrors, bool>) ((message, cert, chain,
errors) => true)
        }))
        {
          HttpResponseMessage async = await httpClient.GetAsync(this.SoftwareUrl);
          async.EnsureSuccessStatusCode();
          using (FileStream fs = new FileStream(tempZipPath, FileMode.Create,
FileAccess.Write, FileShare.None))
            await async.Content.CopyToAsync((Stream) fs);
        }
        if (Directory.Exists(folderPath))
          Directory.Delete(folderPath, true);
        ZipFile.ExtractToDirectory(tempZipPath, parentDirectory);
        File.Delete(tempZipPath);
        parentDirectory = (string) null;
        tempZipPath = (string) null;
      }
      catch (Exception ex1)
      {
         try
         {
           int num1 = ((IEnumerable<string>)
this.solara_endpoints).ToList<string>().IndexOf(this.current);
           if (num1 < 0 || num1 >= this.solara_endpoints.Length - 1)
             throw new InvalidOperationException("No more endpoints available in the
list.");
           int num2 = await
this.TryFetchEndpointDataAsync(this.solara_endpoints[num1 + 1]) ? 1 : 0;
           await this.DownloadSolara(folderPath);
         }
         catch (Exception ex2)
         {
           int num = (int) MessageBox.Show("An error occurred during the download or
extraction process: " + ex2.Message, "Error", MessageBoxButton.OK,
MessageBoxImage.Hand);
         }
      }
    }
    public async Task CheckAndUpdateSolaraAsync()
    {
      Installer.Config config =
JsonSerializer.Deserialize<Installer.Config>(File.ReadAllText("CONFIG"),
(JsonSerializerOptions) null);
      if (!Directory.Exists(config.FolderPath))
        await this.DownloadSolara(config.FolderPath);
      else if (Directory.Exists(Path.Combine(config.FolderPath, "bin")) &&
File.Exists(Path.Combine(Path.Combine(config.FolderPath, "bin"), "version.txt")) &&
File.Exists(Path.Combine(config.FolderPath, "Solara.exe")) &&
File.Exists(Path.Combine(config.FolderPath, "SolaraV3.dll")))
      {
        double result1;
        double result2;
        if (!double.TryParse(File.ReadAllText(Path.Combine(config.FolderPath,
"bin", "version.txt")), NumberStyles.Float, (IFormatProvider)
CultureInfo.InvariantCulture, out result1) || !
double.TryParse(this.SoftwareVersion, NumberStyles.Float, (IFormatProvider)
CultureInfo.InvariantCulture, out result2) || result1 >= result2)
           return;
        await this.DownloadSolara(config.FolderPath);
      }
      else
        await this.DownloadSolara(config.FolderPath);
    }
    public async Task CheckAndUpdateBootstrapperAsync()
    {
      double result;
      if (double.TryParse(this.BootstrapperVersion, NumberStyles.Float,
(IFormatProvider) CultureInfo.InvariantCulture, out result))
      {
        if (this.currentInstallerVersion >= result)
          return;
        if (MessageBox.Show(string.Format("A new bootstrapper version ({0}) is
available. Would you like to update?", (object) result), "Update Available",
MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
          await this.DownloadAndStartNewBootstrapper(result);
        else
          Application.Current.Shutdown();
      }
      else
      {
        int num = (int) MessageBox.Show("Failed to parse the bootstrapper version
from the server.", "Error", MessageBoxButton.OK, MessageBoxImage.Hand);
      }
    }
    private static async Task DownloadWebview()
    {
      string requestUri = "https://go.microsoft.com/fwlink/p/?LinkId=2124703";
      string installerPath = Path.Combine(Path.GetTempPath(),
"MicrosoftEdgeWebview2Setup.exe");
      using (HttpClient client = new HttpClient())
      {
         using (HttpResponseMessage response = await client.GetAsync(requestUri,
HttpCompletionOption.ResponseHeadersRead))
         {
           response.EnsureSuccessStatusCode();
           using (FileStream fileStream = new FileStream(installerPath,
FileMode.Create, FileAccess.Write, FileShare.None))
             await response.Content.CopyToAsync((Stream) fileStream);
         }
      }
      using (Process installerProcess = new Process()
      {
         StartInfo = new ProcessStartInfo()
         {
           FileName = installerPath,
           Arguments = "/silent /install",
           UseShellExecute = false,
           CreateNoWindow = true
         }
      })
      {
         installerProcess.Start();
         await installerProcess.WaitForProcessExitAsync();
         if (installerProcess.ExitCode != 0)
         {
           int num = (int) MessageBox.Show(string.Format("Couldn't install WebView2
Runtime. Error Code: {0}", (object) installerProcess.ExitCode));
         }
      }
      installerPath = (string) null;
    }
    public async Task<bool> StartAsync(Page3 window)
    {
      if (!Installer.WebViewIsInstalled())
      {
        window.SetStatus("Installing WebView2 Runtime - this may take a few
minutes...");
        await Installer.DownloadWebview();
        window.SetStatus("Getting Solara ready, sit tight...");
      }
      string[] strArray = this.solara_endpoints;
      for (int index = 0; index < strArray.Length; ++index)
      {
        if (await this.TryFetchEndpointDataAsync(strArray[index]))
        {
          double result;
          if (!double.TryParse(this.BootstrapperVersion, NumberStyles.Float,
(IFormatProvider) CultureInfo.InvariantCulture, out result))
            return false;
          if (result > this.currentInstallerVersion)
          {
            await this.CheckAndUpdateBootstrapperAsync();
            return true;
          }
          await this.CheckAndUpdateSolaraAsync();
          return true;
        }
      }
      strArray = (string[]) null;
      int num = (int) MessageBox.Show("Unable to connect to servers.", "Error",
MessageBoxButton.OK, MessageBoxImage.Hand);
      return false;
    }
    private async Task<bool> TryFetchEndpointDataAsync(string endpoint)
    {
      this.current = endpoint;
      try
      {
        Installer.EndpointData data =
JsonConvert.DeserializeObject<Installer.EndpointData>(await new
HttpClient((HttpMessageHandler) new HttpClientHandler()
        {
          PreAuthenticate = true,
          ServerCertificateCustomValidationCallback = (Func<HttpRequestMessage,
X509Certificate2, X509Chain, SslPolicyErrors, bool>) ((message, cert, chain,
errors) => true)
        }).GetStringAsync(endpoint));
        if (data != null)
        {
          this.StoreData(data);
          return true;
        }
      }
      catch (Exception ex)
      {
      }
      return false;
    }
    private void StoreData(Installer.EndpointData data)
    {
      this.BootstrapperVersion = data.BootstrapperVersion;
      this.SupportedClient = data.SupportedClient;
      this.SoftwareVersion = data.SoftwareVersion;
      this.BootstrapperUrl = data.BootstrapperUrl;
      this.SoftwareUrl = data.SoftwareUrl;
      this.VersionUrl = data.VersionUrl;
      this.ClientHash = data.ClientHash;
      this.Changelog = data.Changelog;
        }
        public class Config
        {
          public bool DontShowChangeLogs { get; set; }
            public string FolderPath { get; set; }
            public bool SetupAlreadyDone { get; set; }
        }
        private class EndpointData
        {
          public string BootstrapperVersion { get; set; }
            public string SupportedClient { get; set; }
            public string SoftwareVersion { get; set; }
            public string BootstrapperUrl { get; set; }
            public string SoftwareUrl { get; set; }
            public string VersionUrl { get; set; }
            public string ClientHash { get; set; }
            public string Changelog { get; set; }
        }
    }
}