using Deploymentcenter.Client;
using Serilog;

namespace Predictalytics.Hosting;

/// <summary>
/// Checks the Deployment Center UpdateService for a newer release
/// (GET /api/updateservice/v1/check, no token needed).
///
/// The check itself only reads metadata. Installing is done by the standalone
/// update-agent, which replaces the running installation and therefore has to be
/// started explicitly by the user.
/// </summary>
public static class DcUpdateService
{
    private const string AgentFileName = "update-agent.exe";

    public static async Task<UpdateCheckResult> CheckAsync(string channel, CancellationToken ct = default)
    {
        var client = new UpdateClient();
        return await client.CheckForUpdateAsync(
            baseUrl: DcConfig.BaseUrl,
            projectId: DcConfig.ProductSlug,
            currentVersion: DcConfig.AppVersion,
            channel: string.IsNullOrWhiteSpace(channel) ? "prod" : channel,
            cancellationToken: ct).ConfigureAwait(false);
    }

    /// <summary>Path of the update agent next to the exe, or null if it was not deployed.</summary>
    public static string? FindUpdateAgent()
    {
        var path = Path.Combine(AppContext.BaseDirectory, AgentFileName);
        return File.Exists(path) ? path : null;
    }

    /// <summary>
    /// Hands control to the update agent and ends this process. Returns false if the agent
    /// is not present — then the update has to be installed by hand.
    /// </summary>
    public static bool LaunchAgent(string channel)
    {
        var agent = FindUpdateAgent();
        if (agent is null)
        {
            Log.Warning("Update-Agent ({Agent}) liegt nicht neben der Anwendung — Update bitte manuell einspielen.", AgentFileName);
            return false;
        }

        Log.Information("Starte Update-Agent {Agent} (Kanal {Channel}) und beende die Anwendung...", agent, channel);
        return UpdateClient.LaunchUpdateAgent(
            agentPath: agent,
            projectId: DcConfig.ProductSlug,
            channel: string.IsNullOrWhiteSpace(channel) ? "prod" : channel,
            action: "update",
            version: "latest",
            exitCurrentApp: true);
    }
}
