// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using Xunit;

namespace Microsoft.Extensions.FileProviders.Embedded.Manifest
{
    public class ManifestEntryTests
    {
        [Fact]
        public void TraversingAFile_ReturnsUnknownPath()
        {
            // Arrange
            var file = new ManifestFile("a", "a.b.c");

            // Act
            var result = file.Traverse(".");

            // Assert
            Assert.Equal(ManifestEntry.UnknownPath, result);
        }

        [Fact]
        public void TraversingANonExistingFile_ReturnsUnknownPath()
        {
            // Arrange
            var directory = ManifestDirectory.CreateDirectory("a", Array.Empty<ManifestEntry>());

            // Act
            var result = directory.Traverse("missing.txt");

            // Assert
            Assert.Equal(ManifestEntry.UnknownPath, result);
        }

        [Fact]
        public void TraversingWithDot_ReturnsSelf()
        {
            // Arrange
            var directory = ManifestDirectory.CreateDirectory("a", Array.Empty<ManifestEntry>());

            // Act
            var result = directory.Traverse(".");

            // Assert
            Assert.Same(directory, result);
        }

        [Fact]
        public void TraversingWithDotDot_ReturnsParent()
        {
            // Arrange
            var childDirectory = ManifestDirectory.CreateDirectory("b", Array.Empty<ManifestEntry>());
            var directory = ManifestDirectory.CreateDirectory("a", new[] { childDirectory });

            // Act
            var result = childDirectory.Traverse("..");

            // Assert
            Assert.Equal(directory, result);
        }

        [Fact]
        public void TraversingRootDirectoryWithDotDot_ReturnsSinkDirectory()
        {
            // Arrange
            var directory = ManifestDirectory.CreateRootDirectory(Array.Empty<ManifestEntry>());

            // Act
            var result = directory.Traverse("..");

            // Assert
            Assert.Equal(ManifestEntry.UnknownPath, result);
        }

        [Fact]
        public void ScopingAFolderAndTryingToGetAScopedFile_ReturnsSinkDirectory()
        {
            // Arrange
            var directory = ManifestDirectory.CreateRootDirectory(new[] {
                ManifestDirectory.CreateDirectory("a",
                    new[] { new ManifestFile("test1.txt", "text.txt") }),
                ManifestDirectory.CreateDirectory("b",
                    new[] { new ManifestFile("test2.txt", "test2.txt") }) });

            var newRoot = ((ManifestDirectory)directory.Traverse("a")).ToRootDirectory();

            // Act
            var result = newRoot.Traverse("../b/test.txt");

            // Assert
            Assert.Same(ManifestEntry.UnknownPath, result);
        }

        [Theory]
        [InlineData("..")]
        [InlineData(".")]
        [InlineData("file.txt")]
        [InlineData("folder")]
        public void TraversingUnknownPath_ReturnsSinkDirectory(string path)
        {
            // Arrange
            var directory = ManifestEntry.UnknownPath;

            // Act
            var result = directory.Traverse(path);

            // Assert
            Assert.Equal(ManifestEntry.UnknownPath, result);
        }
    }
}
