using System.Linq;

using Gallium;

using Nitride.IO.Contents;

using Xunit;
using Xunit.Abstractions;

using Zio;

namespace Nitride.IO.Tests;

public class GetEntityByPathTests : NitrideIOTestBase
{
    public GetEntityByPathTests(ITestOutputHelper output)
        : base(output)
    {
    }

    [Fact]
    public void FoundFile()
    {
        // Set up the test.
        using NitrideIOTestContext context = this.CreateContext();

        // Set up the file.
        IFileSystem fileSystem = context.FileSystem;

        fileSystem.CreateFile("/b1.txt");
        fileSystem.CreateFile("/c1.md");

        // Set up the operation.
        ReadFiles readFiles = context.Resolve<ReadFiles>();

        // Read and replace the paths.
        IOrderedEnumerable<string> output = readFiles.WithPattern("/**")
            .Run()
            .GetEntityByPath("/c1.md", out Entity? found)
            .Select(
                x => x.Get<UPath>()
                    .ToString())
            .OrderBy(x => x);

        // Verify the results.
        Assert.Equal(
            new[]
            {
                "/b1.txt",
            },
            output);

        Assert.NotNull(found);
        Assert.Equal("/c1.md", found!.Get<UPath>());
    }

    [Fact]
    public void FoundFileAndKeep()
    {
        // Set up the test.
        using NitrideIOTestContext context = this.CreateContext();

        // Set up the file.
        IFileSystem fileSystem = context.FileSystem;

        fileSystem.CreateFile("/b1.txt");
        fileSystem.CreateFile("/c1.md");

        // Set up the operation.
        ReadFiles readFiles = context.Resolve<ReadFiles>();

        // Read and replace the paths.
        IOrderedEnumerable<string> output = readFiles.WithPattern("/**")
            .Run()
            .GetEntityByPath("/c1.md", out Entity? found, IfFoundOutput.ReturnInOutput)
            .Select(
                x => x.Get<UPath>()
                    .ToString())
            .OrderBy(x => x);

        // Verify the results.
        Assert.Equal(
            new[]
            {
                "/b1.txt",
                "/c1.md",
            },
            output);

        Assert.NotNull(found);
        Assert.Equal("/c1.md", found!.Get<UPath>());
    }

    [Fact]
    public void NotFoundFile()
    {
        // Set up the test.
        using NitrideIOTestContext context = this.CreateContext();

        // Set up the file.
        IFileSystem fileSystem = context.FileSystem;

        fileSystem.CreateFile("/b1.txt");
        fileSystem.CreateFile("/c1.md");

        // Set up the operation.
        ReadFiles readFiles = context.Resolve<ReadFiles>();

        // Read and replace the paths.
        IOrderedEnumerable<string> output = readFiles.WithPattern("/**")
            .Run()
            .GetEntityByPath("/not-found.md", out Entity? found)
            .Select(
                x => x.Get<UPath>()
                    .ToString())
            .OrderBy(x => x);

        // Verify the results.
        Assert.Equal(
            new[]
            {
                "/b1.txt",
                "/c1.md",
            },
            output);

        Assert.Null(found);
    }
}