using System.Text;
using Microsoft.Extensions.Configuration;
using ROLAC.API.Services.Storage;
using Xunit;

namespace ROLAC.API.Tests.Services;

public class LocalDiskFileStorageTests : IDisposable
{
    private readonly string _root = Path.Combine(Path.GetTempPath(), "rolac-test-" + Guid.NewGuid());

    private LocalDiskFileStorage Build()
    {
        var config = new ConfigurationBuilder()
            .AddInMemoryCollection(new Dictionary<string, string?> { ["Storage:LocalRoot"] = _root })
            .Build();
        return new LocalDiskFileStorage(config);
    }

    [Fact]
    public async Task SaveThenOpen_RoundTrips()
    {
        var fs = Build();
        using var input = new MemoryStream(Encoding.UTF8.GetBytes("hello"));
        var path = await fs.SaveAsync(input, "finance/receipts/2026/5/1-r.txt");

        await using var read = await fs.OpenReadAsync(path);
        Assert.NotNull(read);
        using var sr = new StreamReader(read!);
        Assert.Equal("hello", await sr.ReadToEndAsync());
    }

    [Fact]
    public async Task OpenRead_ReturnsNull_WhenMissing()
    {
        var fs = Build();
        Assert.Null(await fs.OpenReadAsync("finance/receipts/none.txt"));
    }

    [Fact]
    public async Task Save_RejectsPathTraversal()
    {
        var fs = Build();
        using var input = new MemoryStream(Encoding.UTF8.GetBytes("x"));
        await Assert.ThrowsAsync<ArgumentException>(() => fs.SaveAsync(input, "../escape.txt"));
    }

    public void Dispose()
    {
        if (Directory.Exists(_root)) Directory.Delete(_root, recursive: true);
    }
}
