using System;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using Microsoft.Extensions.Time.Testing;
using StellaOps.Auth.Client;
using Xunit;

namespace StellaOps.Auth.Client.Tests;

public class TokenCacheTests
{
    [Fact]
    public async Task InMemoryTokenCache_ExpiresEntries()
    {
        var timeProvider = new FakeTimeProvider(DateTimeOffset.Parse("2025-01-01T00:00:00Z"));
        var cache = new InMemoryTokenCache(timeProvider, TimeSpan.FromSeconds(5));

        var entry = new StellaOpsTokenCacheEntry("token", "Bearer", timeProvider.GetUtcNow() + TimeSpan.FromSeconds(10), new[] { "scope" });
        await cache.SetAsync("key", entry);

        var retrieved = await cache.GetAsync("key");
        Assert.NotNull(retrieved);

        timeProvider.Advance(TimeSpan.FromSeconds(12));

        retrieved = await cache.GetAsync("key");
        Assert.Null(retrieved);
    }

    [Fact]
    public async Task FileTokenCache_PersistsEntries()
    {
        var directory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N"));
        try
        {
            var timeProvider = new FakeTimeProvider(DateTimeOffset.UtcNow);
            var cache = new FileTokenCache(directory, timeProvider, TimeSpan.Zero);

            var entry = new StellaOpsTokenCacheEntry("token", "Bearer", timeProvider.GetUtcNow() + TimeSpan.FromMinutes(5), new[] { "scope" });
            await cache.SetAsync("key", entry);

            var retrieved = await cache.GetAsync("key");
            Assert.NotNull(retrieved);
            Assert.Equal("token", retrieved!.AccessToken);

            await cache.RemoveAsync("key");
            retrieved = await cache.GetAsync("key");
            Assert.Null(retrieved);
        }
        finally
        {
            if (Directory.Exists(directory))
            {
                Directory.Delete(directory, recursive: true);
            }
        }
    }
}
