using System.Diagnostics;

namespace SpaceGame.Api.Universe.Simulation;

public sealed class TelemetryService : IDisposable
{
    private readonly Process _process = Process.GetCurrentProcess();
    private readonly Timer _timer;
    private double _cpuPercent;
    private DateTime _lastSampleTime;
    private TimeSpan _lastCpuTime;

    public TelemetryService()
    {
        _process.Refresh();
        _lastSampleTime = DateTime.UtcNow;
        _lastCpuTime = _process.TotalProcessorTime;
        _timer = new Timer(Sample, null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
    }

    private void Sample(object? _)
    {
        _process.Refresh();
        var now = DateTime.UtcNow;
        var cpu = _process.TotalProcessorTime;
        var elapsed = (now - _lastSampleTime).TotalSeconds;
        var cpuUsed = (cpu - _lastCpuTime).TotalSeconds;
        Volatile.Write(ref _cpuPercent, elapsed > 0 ? cpuUsed / elapsed / Environment.ProcessorCount * 100.0 : 0);
        _lastSampleTime = now;
        _lastCpuTime = cpu;
    }

    public double CpuPercent => Volatile.Read(ref _cpuPercent);
    public long WorkingSetBytes => _process.WorkingSet64;
    public long GcMemoryBytes => GC.GetTotalMemory(false);
    public int ThreadCount => _process.Threads.Count;
    public TimeSpan Uptime => DateTime.UtcNow - _process.StartTime.ToUniversalTime();

    public void Dispose()
    {
        _timer.Dispose();
        _process.Dispose();
    }
}
