using System.Text;
using System.Text.Json;
using Microsoft.Extensions.Logging;
using PSLauncher.Core.Configuration;
using PSLauncher.Models;

namespace PSLauncher.Core.Manifests;

public sealed class ManifestCache : IManifestCache
{
    private const string FileName = "manifest-cache.json";
    private static readonly JsonSerializerOptions JsonOptions = new()
    {
        PropertyNameCaseInsensitive = true,
    };

    private readonly IConfigStore _configStore;
    private readonly ILogger<ManifestCache> _logger;

    public ManifestCache(IConfigStore configStore, ILogger<ManifestCache> logger)
    {
        _configStore = configStore;
        _logger = logger;
    }

    public string GetCachedFilePath() => Path.Combine(_configStore.ConfigDirectory, FileName);

    public async Task SaveAsync(string rawJson, CancellationToken ct)
    {
        var path = GetCachedFilePath();
        var tmp = path + ".tmp";
        try
        {
            await File.WriteAllTextAsync(tmp, rawJson, Encoding.UTF8, ct).ConfigureAwait(false);
            // Atomic swap : si on est interrompu pendant l'écriture, le cache reste valide.
            File.Move(tmp, path, overwrite: true);
            _logger.LogDebug("Manifest cached to {Path} ({Bytes} bytes)", path, rawJson.Length);
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "Failed to cache manifest to disk (non-fatal)");
            try { if (File.Exists(tmp)) File.Delete(tmp); } catch { }
        }
    }

    public async Task<RemoteManifest?> TryLoadAsync(CancellationToken ct)
    {
        var path = GetCachedFilePath();
        if (!File.Exists(path)) return null;
        try
        {
            var raw = await File.ReadAllTextAsync(path, Encoding.UTF8, ct).ConfigureAwait(false);
            return JsonSerializer.Deserialize<RemoteManifest>(raw, JsonOptions);
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "Failed to read manifest cache from {Path}", path);
            return null;
        }
    }
}
