using System;
using System.Globalization;
using System.IO;
using System.Text;

namespace MultiWheelC.TrajectoryPlanning.TrajectoryObservation;

/// <summary>Buffers a readable text report for one trajectory observation session.</summary>
public sealed class TrajectoryObservationReportWriter
{
    private readonly long _sessionId;
    private readonly string _reportDirectory;
    private readonly StringBuilder _content = new StringBuilder();
    private readonly object _sync = new object();

    public TrajectoryObservationReportWriter(long sessionId, string reportDirectory = null)
    {
        if (sessionId <= 0)
            throw new ArgumentOutOfRangeException(nameof(sessionId));

        _sessionId = sessionId;
        _reportDirectory = reportDirectory ??
            Path.Combine(Environment.CurrentDirectory, "TrajectoryObservationReports");
        AppendHeader();
    }

    public string FilePath
    {
        get
        {
            return Path.Combine(_reportDirectory, "trajectory-observation-session-" +
                _sessionId.ToString(CultureInfo.InvariantCulture) + ".txt");
        }
    }

    public void Append(string text)
    {
        if (string.IsNullOrEmpty(text))
            return;

        lock (_sync)
        {
            _content.Append(DateTimeOffset.Now.ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture));
            _content.Append(" | ");
            _content.AppendLine(text);
        }
    }

    public string Save()
    {
        lock (_sync)
        {
            Directory.CreateDirectory(_reportDirectory);
            File.WriteAllText(FilePath, _content.ToString(), new UTF8Encoding(false));
            return FilePath;
        }
    }

    private void AppendHeader()
    {
        _content.AppendLine("EM trajectory observation report");
        _content.AppendLine("session=" + _sessionId.ToString(CultureInfo.InvariantCulture));
        _content.AppendLine("OBSERVE_ONLY: no chassis command is sent.");
        _content.AppendLine("reportGeneratedUtc=" + DateTimeOffset.UtcNow.ToString("O", CultureInfo.InvariantCulture));
        _content.AppendLine();
    }
}
