using System.IO;
using System.Text.Json;
using ConeCalorimeter.Models;
using Serilog;

namespace ConeCalorimeter.Services;

public sealed class JsonHeatReleaseResponseCalibrationStore
{
    private static readonly JsonSerializerOptions JsonOptions = new()
    {
        PropertyNameCaseInsensitive = true,
        WriteIndented = true
    };

    public JsonHeatReleaseResponseCalibrationStore()
        : this(Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
            "ConeCalorimeter",
            "heat-release-response-calibration.json"))
    {
    }

    public JsonHeatReleaseResponseCalibrationStore(string storagePath)
    {
        StoragePath = storagePath;
    }

    public string StoragePath { get; }

    public HeatReleaseResponseCalibration? Load()
    {
        if (!File.Exists(StoragePath))
        {
            return null;
        }

        try
        {
            using var stream = File.OpenRead(StoragePath);
            return JsonSerializer.Deserialize<HeatReleaseResponseCalibration>(stream, JsonOptions);
        }
        catch (Exception ex) when (ex is IOException or UnauthorizedAccessException or JsonException)
        {
            Log.Warning(ex, "Heat release response calibration load failed. Path={Path}.", StoragePath);
            return null;
        }
    }

    public void Save(HeatReleaseResponseCalibration calibration)
    {
        var directory = Path.GetDirectoryName(StoragePath);
        if (!string.IsNullOrWhiteSpace(directory))
        {
            Directory.CreateDirectory(directory);
        }

        var tempPath = $"{StoragePath}.tmp";
        using (var stream = File.Create(tempPath))
        {
            JsonSerializer.Serialize(stream, calibration, JsonOptions);
        }

        File.Move(tempPath, StoragePath, true);
    }
}
