using System.Reflection;
using OF_DL.Models.OfdlApi;
using OF_DL.Services;

namespace OF_DL.Tests.Services;

[CollectionDefinition("NonParallel", DisableParallelization = true)]
public class NonParallelCollection
{
}

internal sealed class DynamicRulesCacheScope : IDisposable
{
    private static readonly FieldInfo s_rulesField =
        typeof(ApiService).GetField("s_cachedDynamicRules", BindingFlags.NonPublic | BindingFlags.Static) ??
        throw new InvalidOperationException("Unable to access cached rules field.");

    private static readonly FieldInfo s_expirationField =
        typeof(ApiService).GetField("s_cachedDynamicRulesExpiration",
            BindingFlags.NonPublic | BindingFlags.Static) ??
        throw new InvalidOperationException("Unable to access cached rules expiration field.");

    private readonly object? _priorRules;
    private readonly DateTime? _priorExpiration;

    public DynamicRulesCacheScope(DynamicRules rules)
    {
        _priorRules = s_rulesField.GetValue(null);
        _priorExpiration = (DateTime?)s_expirationField.GetValue(null);

        s_rulesField.SetValue(null, rules);
        s_expirationField.SetValue(null, DateTime.UtcNow.AddHours(1));
    }

    public void Dispose()
    {
        s_rulesField.SetValue(null, _priorRules);
        s_expirationField.SetValue(null, _priorExpiration);
    }
}

internal sealed class CurrentDirectoryScope : IDisposable
{
    private readonly string _original;

    public CurrentDirectoryScope(string path)
    {
        _original = Environment.CurrentDirectory;
        Environment.CurrentDirectory = path;
    }

    public void Dispose() => Environment.CurrentDirectory = _original;
}
