using LightlessSync.Interop.Ipc;
using LightlessSync.LightlessConfiguration;
using LightlessSync.Services.Mediator;
using Microsoft.Extensions.Logging;

namespace LightlessSync.Services;

public sealed class PenumbraTempCollectionJanitor : DisposableMediatorSubscriberBase
{
    private readonly IpcManager _ipc;
    private readonly LightlessConfigService _config; 
    private int _ran;

    public PenumbraTempCollectionJanitor(
        ILogger<PenumbraTempCollectionJanitor> logger,
        LightlessMediator mediator,
        IpcManager ipc,
        LightlessConfigService config) : base(logger, mediator)
    {
        _ipc = ipc;
        _config = config;

        Mediator.Subscribe<PenumbraInitializedMessage>(this, _ => CleanupOrphansOnBoot());
    }

    public void Register(Guid id)
    {
        if (id == Guid.Empty) return;
        if (_config.Current.OrphanableTempCollections.Add(id))
            _config.Save();
    }

    public void Unregister(Guid id)
    {
        if (id == Guid.Empty) return;
        if (_config.Current.OrphanableTempCollections.Remove(id))
            _config.Save();
    }

    private void CleanupOrphansOnBoot()
    {
        if (Interlocked.Exchange(ref _ran, 1) == 1)
            return;

        if (!_ipc.Penumbra.APIAvailable)
            return;

        var ids = _config.Current.OrphanableTempCollections.ToArray();
        if (ids.Length == 0)
            return;

        var appId = Guid.NewGuid();
        Logger.LogInformation("Cleaning up {count} orphaned Lightless temp collections found in configuration", ids.Length);

        foreach (var id in ids)
        {
            try
            {
                _ipc.Penumbra.RemoveTemporaryCollectionAsync(Logger, appId, id)
                    .GetAwaiter().GetResult();
            }
            catch (Exception ex)
            {
                Logger.LogDebug(ex, "Failed removing orphaned temp collection {id}", id);
            }
        }

        _config.Current.OrphanableTempCollections.Clear();
        _config.Save();
    }
}