public async Task <object> GetChanges([FromRoute(Name = "branch")] string updateBranch,
                                              [FromQuery(Name = "version")] string urlVersion,
                                              [FromQuery(Name = "os")] OperatingSystem operatingSystem,
                                              [FromQuery(Name = "runtimeVer")] string urlRuntimeVersion,
                                              [FromQuery(Name = "runtime")] Runtime runtime = Runtime.DotNet,
                                              [FromQuery(Name = "arch")] Architecture arch  = Architecture.X64)
        {
            Response.Headers[HeaderNames.CacheControl] = GetCacheControlHeader(DateTime.UtcNow);

            var updateFiles = await _updateFileService.Find(updateBranch, operatingSystem, runtime, arch, false, 5, urlVersion, urlRuntimeVersion);

            var response = new List <UpdatePackage>();

            foreach (var updateFile in updateFiles)
            {
                var           update        = updateFile.Update.Value;
                UpdateChanges updateChanges = null;

                if (update.New.Count != 0 || update.Fixed.Count != 0)
                {
                    updateChanges = new UpdateChanges
                    {
                        New   = update.New,
                        Fixed = update.Fixed
                    };
                }

                response.Add(new UpdatePackage
                {
                    Version     = update.Version,
                    ReleaseDate = update.ReleaseDate,
                    Filename    = updateFile.Filename,
                    Url         = updateFile.Url,
                    Changes     = updateChanges,
                    Hash        = updateFile.Hash,
                    Branch      = update.Branch.ToString().ToLower()
                });
            }

            return(response);
        }
        public async Task <object> GetUpdates([FromRoute(Name = "branch")] string updateBranch,
                                              [FromQuery(Name = "version")] string urlVersion,
                                              [FromQuery(Name = "os")] OperatingSystem operatingSystem,
                                              [FromQuery(Name = "runtime")] Runtime runtime,
                                              [FromQuery(Name = "runtimeVer")] string urlRuntimeVersion,
                                              [FromQuery(Name = "arch")] Architecture arch,
                                              [FromQuery(Name = "active")] bool activeInstall = true)
        {
            Response.Headers[HeaderNames.CacheControl] = GetCacheControlHeader(DateTime.UtcNow);

            // Check given version
            if (!Version.TryParse(urlVersion, out var version))
            {
                return(new
                {
                    ErrorMessage = "Invalid version number specified."
                });
            }

            var userAgentInfo = new UserAgentInfo(Request.Headers["User-Agent"].ToString());

            // Dont' send metrics for dev/debug instances
            if (version.Major < 10)
            {
                var remoteIpAddress = Request.HttpContext.Connection.RemoteIpAddress;

                Metrics.Write("userstats",
                              new Dictionary <string, object>
                {
                    { "source", remoteIpAddress }
                },
                              new Dictionary <string, string>
                {
                    { "program", _project },
                    { "requestApp", userAgentInfo.App ?? "Unknown" },
                    { "branch", updateBranch },
                    { "version", urlVersion },
                    { "os", operatingSystem.ToString() },
                    { "osName", userAgentInfo.Name ?? "Unknown" },
                    { "osVersion", userAgentInfo.OsVersion ?? "Unknown" },
                    { "runtime", runtime.ToString() },
                    { "runtimeVersion", urlRuntimeVersion },
                    { "arch", arch.ToString() },
                    { "activeinstall", activeInstall.ToString() }
                });
            }

            var files = await _updateFileService.Find(updateBranch, operatingSystem, runtime, arch, false, 1, urlVersion, urlRuntimeVersion);

            var updateFile = files.FirstOrDefault();

            if (updateFile == null)
            {
                return(new UpdatePackageContainer
                {
                    Available = false
                });
            }

            var update = updateFile.Update.Value;

            // Compare given version and update version
            var updateVersion = new Version(update.Version);

            if (updateVersion.CompareTo(version) <= 0)
            {
                return(new UpdatePackageContainer
                {
                    Available = false
                });
            }

            // Get the update changes
            UpdateChanges updateChanges = null;

            if (update.New.Count != 0 || update.Fixed.Count != 0)
            {
                updateChanges = new UpdateChanges
                {
                    New   = update.New,
                    Fixed = update.Fixed
                };
            }

            return(new UpdatePackageContainer
            {
                Available = true,
                UpdatePackage = new UpdatePackage
                {
                    Version = update.Version,
                    ReleaseDate = update.ReleaseDate,
                    Filename = updateFile.Filename,
                    Url = updateFile.Url,
                    Changes = updateChanges,
                    Hash = updateFile.Hash,
                    Branch = update.Branch.ToString().ToLower(),
                    Runtime = updateFile.Runtime.ToString().ToLower()
                }
            });
        }