private void PrintReleaseInfo(GitHubReleases release, TimeSpan releaseAge)
        {
            if (this.latestRelease == null)
            {
                var print = "Latest filter release was ";
                if (releaseAge.TotalDays >= 1)
                {
                    print += Math.Floor(releaseAge.TotalDays) + " days, ";
                }
                if (releaseAge.Hours > 0)
                {
                    print += releaseAge.Hours + " hours, ";
                }
                print += releaseAge.Minutes + " minutes ago";
                Console.WriteLine(print);
            }

            else
            {
                Console.WriteLine("NEW FILTER RELEASE!!!! NEVERSINK TOOK OUR ENERGY!");
                this.OnNewFilterVersions?.Invoke(release, EventArgs.Empty);
            }

            Console.WriteLine(release.Name);
        }
        private GitHubReleases GetLastestRelease()
        {
            this.client.Headers.Add("User-Agent: Other");
            var jsonString = this.client.DownloadString(this.apiUrl);
            var jsonObj    = GitHubReleases.FromJson(jsonString);

            return(jsonObj.First());
        }
        private void ProcessRelease(GitHubReleases release)
        {
            var now         = DateTimeOffset.Now;
            var releaseTime = release.PublishedAt;
            var releaseAge  = now.Subtract(releaseTime);

            if (this.latestRelease == null || !release.PublishedAt.Equals(this.latestRelease.PublishedAt))
            {
                this.PrintReleaseInfo(release, releaseAge);
                this.latestRelease = release;
            }
            else
            {
                Console.WriteLine("no new release :(");
            }
        }
        private static async Task DoUpdate(GitHubReleases gitHubReleases, GitHubReleases.Release release, CancelableProgressBarWindow <long> progress)
        {
            CancellationToken token = progress.GetCancellationToken();

            byte[]? newExe = await Task.Run(() => {
                return(gitHubReleases.DownloadReleaseAsset(
                           release.Assets.First(assert => assert.Name == "Osoyoos.exe"),
                           progress, token));
            });

            if (newExe is null)
            {
                progress.Complete = true;
                _ = MessageBox.Show("Couldn't download release!", "Download Failed!", MessageBoxButton.OK);
            }
            else
            {
                progress.Status = "Applying update";
                // get the name of the host file
                string host    = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
                string oldHost = host + "_old.exe";

                // delete any old backup files
                try
                {
                    File.Delete(oldHost);
                }
                catch { }

                try
                {
                    // backup current/bypass lock
                    File.Move(host, oldHost);
                } catch (Exception ex)
                {
                    Debug.WriteLine(ex.ToString());
                    _ = MessageBox.Show("Couldn't rename running instance!", "Update Failed!", MessageBoxButton.OK);
                    progress.Cancel("couldn't rename running instance");
                    return;
                }

                try
                {
                    // save new file
                    await File.WriteAllBytesAsync(host, newExe, progress.GetCancellationToken());

#if DEBUG
                    await Task.Delay(1000, token); // test
#endif
                    // setup new instance
                    ProcessStartInfo newProcess = new(host);
                    newProcess.ArgumentList.Add(App.DeleteOldCommand);
                    newProcess.ArgumentList.Add(oldHost);

                    // final chance
                    token.ThrowIfCancellationRequested();

                    if (System.Diagnostics.Process.Start(newProcess) is not null)
                    {
                        // startup of new instance worked, terminate ourselves without delay
                        Environment.Exit(0);
                    }
                    // something went wrong
                    throw new OperationCanceledException("launch failure!");
                } catch
                {
                    progress.Cancel("couldn't launch new instance");
                    // delete new copy/rollback
                    try
                    {
                        File.Delete(host);
                    }
                    catch { }
                    // rollback
                    File.Move(oldHost, host);
                    throw; // rethrow
                }
            }
        }
        //####################################################################################################################################################################

        /// <summary>
        /// Get all releases from the GitHub repository
        /// </summary>
        /// see: https://github.com/nixxquality/GitHubUpdate
        public async Task GetAllGitHubReleases()
        {
            try
            {
                ErrorOccuredWhileLoadingReleases = false;
                ErrorMessage = string.Empty;
                GitHubReleases?.Clear();

                if (!IsGitHubRepoAssigned)
                {
                    GitHubReleases = null; return;
                }

                // example url: https://github.com/M1S2/AssemblyInfoHelper
                string[] urlSplitted = AssemblyInfoHelperClass.GitHubRepoUrl.Split('/');
                if (urlSplitted.Length < 5)
                {
                    return;
                }
                string repoOwner = urlSplitted[3];
                string repoName  = urlSplitted[4];

                GitHubClient gitHubClient = new GitHubClient(new ProductHeaderValue("AssemblyInfoHelper-UpdateCheck"));

                List <Release> originalReleases = new List <Release>(await gitHubClient.Repository.Release.GetAll(repoOwner, repoName));

                SemVersion currentVersion  = stripInitialV(AssemblyInfoHelperClass.AssemblyVersion);
                SemVersion previousVersion = new SemVersion(0, 0, 0);
                originalReleases.Reverse();

                List <GitHubRelease> tmpGitHubReleases = new List <GitHubRelease>();

                foreach (Release release in originalReleases)
                {
                    SemVersion releaseVersion = stripInitialV(release.TagName);

                    tmpGitHubReleases.Add(new GitHubRelease()
                    {
                        Name            = release.Name,
                        ReleaseTime     = release.CreatedAt.ToLocalTime(),
                        Version         = releaseVersion,
                        ReleaseTimeType = (releaseVersion > currentVersion ? GitHubReleaseTimeTypes.NEW : (releaseVersion == currentVersion ? GitHubReleaseTimeTypes.CURRENT : GitHubReleaseTimeTypes.OLD)),
                        ReleaseURL      = release.HtmlUrl,
                        ReleaseNotes    = release.Body,
                        ReleaseType     = getReleaseTypeFromVersions(releaseVersion, previousVersion),

                        /* Asset Names should be:
                         * For binaries: %ProjectName%_Binaries.zip, %ProjectName%.zip, %ProjectName%_v1.0.0.zip, bin.zip
                         * For installer: %ProjectName%_Installer.zip, Installer.zip, Setup.zip, Setup.exe
                         */
                        BinAsset       = release.Assets.Where(a => a.Name.ToLower().Contains("bin") || (a.Name.ToLower().StartsWith(AssemblyInfoHelperClass.AssemblyTitle.ToLower()) && !a.Name.ToLower().Contains("inst") && !a.Name.ToLower().Contains("setup"))).FirstOrDefault(),
                        InstallerAsset = release.Assets.Where(a => a.Name.ToLower().Contains("inst") || a.Name.ToLower().Contains("setup")).FirstOrDefault()
                    });

                    previousVersion = releaseVersion;
                }

                tmpGitHubReleases.Reverse();
                foreach (GitHubRelease r in tmpGitHubReleases)
                {
                    GitHubReleases.Add(r);
                }

                if (SemaphoreGetReleases.CurrentCount == 0)
                {
                    SemaphoreGetReleases.Release();
                }
            }
            catch (Exception ex)
            {
                ErrorOccuredWhileLoadingReleases = true;
                ErrorMessage = ex.Message + (ex.InnerException != null ? Environment.NewLine + ex.InnerException.Message : "");
                if (SemaphoreGetReleases.CurrentCount == 0)
                {
                    SemaphoreGetReleases.Release();
                }
            }
        }