using Nexus.Contracts.Devices;
using NexusShell.Services;

namespace NexusShell.Agent;

public sealed class NexusDeviceRegistrationService
{
    private readonly NexusApiClient _apiClient;
    private readonly NexusAgentConfig _config;
    private readonly NexusInventoryService _inventory;
    private readonly ClientVersionInfo _shellVersion;
    private int _registrationBusy;

    public NexusDeviceRegistrationService(
        NexusApiClient apiClient,
        NexusAgentConfig config,
        NexusInventoryService inventory,
        ClientVersionInfo shellVersion)
    {
        _apiClient = apiClient;
        _config = config;
        _inventory = inventory;
        _shellVersion = shellVersion;
    }

    public async Task TryRegisterAsync(CancellationToken cancellationToken = default)
    {
        if (Interlocked.CompareExchange(ref _registrationBusy, 1, 0) != 0)
        {
            return;
        }

        try
        {
            var snapshot = _inventory.CaptureSnapshot();
            var request = new DeviceRegistrationRequest
            {
                DeviceId = _config.DeviceId,
                ComputerName = snapshot.ComputerName,
                Os = snapshot.Os,
                Cpu = snapshot.Cpu,
                Ram = snapshot.Ram,
                Storage = snapshot.Storage,
                Version = _shellVersion.Version,
                AgentVersion = NexusAgentConfig.AgentVersion,
            };

            var ok = await _apiClient.RegisterDeviceAsync(request, cancellationToken);
            if (ok)
            {
                _config.IsRegistered = true;
                _config.RegisteredAtUtc = DateTimeOffset.UtcNow;
                _config.Save();
            }
        }
        finally
        {
            Interlocked.Exchange(ref _registrationBusy, 0);
        }
    }
}
