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

namespace ReactorMaintenance.Simulation;

public static class LevelSerializer
{
    private sealed record LevelFile
    {
        public int Version { get; init; }
        public LevelState? Level { get; init; }
    }

    public static string Serialize(LevelState level)
    {
        return JsonSerializer.Serialize(new LevelFile {
            Version = c_CurrentVersion,
            Level = level
        }, s_Options);
    }

    public static LevelState Deserialize(string json)
    {
        var file = JsonSerializer.Deserialize<LevelFile>(json, s_Options) ?? throw new InvalidOperationException("Level file did not contain a level.");
        if (file.Version != c_CurrentVersion)
            throw new InvalidOperationException($"Unsupported level file version {file.Version}. Expected {c_CurrentVersion}.");

        var level = file.Level ?? throw new InvalidOperationException("Level file did not contain a level.");
        var report = new LevelValidator().Validate(level);
        if (!report.IsValid)
            throw new InvalidOperationException(report.Errors[0].Message);

        return level;
    }

    private const int c_CurrentVersion = 2;

    private static readonly JsonSerializerOptions s_Options = new() {
        WriteIndented = true,
        Converters = { new JsonStringEnumConverter() }
    };
}