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

namespace Sdt.Core;

public sealed class RunEventJsonlRecorder : IDisposable
{
    private static readonly JsonSerializerOptions JsonOptions = new()
    {
        PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
        WriteIndented = false
    };

    static RunEventJsonlRecorder()
    {
        JsonOptions.Converters.Add(new JsonStringEnumConverter());
    }

    private readonly StreamWriter _writer;
    private readonly object _gate = new();
    private bool _disposed;

    public string FilePath { get; }

    private RunEventJsonlRecorder(string filePath, StreamWriter writer)
    {
        FilePath = filePath;
        _writer = writer;
    }

    public static RunEventJsonlRecorder Create(string projectRoot, string category)
    {
        var root = Path.Combine(projectRoot, ".sdt", "events");
        Directory.CreateDirectory(root);
        var fileName = $"{category}-{DateTimeOffset.Now:yyyyMMdd-HHmmss}.jsonl";
        var path = Path.Combine(root, fileName);
        var writer = new StreamWriter(new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read))
        {
            AutoFlush = true
        };
        return new RunEventJsonlRecorder(path, writer);
    }

    public void Write(RunEvent evt)
    {
        lock (_gate)
        {
            if (_disposed)
                return;
            var line = JsonSerializer.Serialize(evt, JsonOptions);
            _writer.WriteLine(line);
        }
    }

    public void Dispose()
    {
        lock (_gate)
        {
            if (_disposed)
                return;
            _disposed = true;
            _writer.Dispose();
        }
    }
}
