using System.Text.Json;
using System.Text.Json.Serialization;

namespace YMhut.Box.Core.Updates;

public sealed record ReleaseManifest(
    string Version,
    string PackageVersion,
    string Channel,
    DateTimeOffset CreatedAt,
    IReadOnlyList<ReleaseFileEntry> Files,
    IReadOnlyList<string> DeletedFiles,
    string BaseDownloadUrl = "",
    string Flavor = "");

public sealed record ReleaseFileEntry(
    string Path,
    long Size,
    string Sha256,
    bool Required = false);

public interface IAppUpdateService
{
    Task<ReleaseManifest?> GetLatestManifestAsync(CancellationToken cancellationToken = default);
}

public static class ReleaseManifestSerializer
{
    public static readonly JsonSerializerOptions Options = new(JsonSerializerDefaults.Web)
    {
        WriteIndented = true,
        DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
    };

    public static async Task<ReleaseManifest> ReadManifestAsync(string path, CancellationToken cancellationToken = default)
    {
        await using var stream = File.OpenRead(path);
        return await JsonSerializer.DeserializeAsync<ReleaseManifest>(stream, Options, cancellationToken).ConfigureAwait(false)
            ?? throw new InvalidDataException("Release manifest is empty or invalid.");
    }

    public static async Task WriteManifestAsync(string path, ReleaseManifest manifest, CancellationToken cancellationToken = default)
    {
        Directory.CreateDirectory(Path.GetDirectoryName(path)!);
        await using var stream = File.Create(path);
        await JsonSerializer.SerializeAsync(stream, manifest, Options, cancellationToken).ConfigureAwait(false);
    }
}
