namespace Voile.VFS;

/// <summary>
/// A virtual file system that provides an abstract interface for manipulating files from various sources.
/// </summary>
public static class VirtualFileSystem
{
    /// <summary>
    /// Mounts a <see cref="IVirtualMountPoint"/>.
    /// This will make files available for this mount point accessible.
    /// </summary>
    /// <param name="mountPoint"></param>
    public static void Mount(IVirtualMountPoint mountPoint)
    {
        mountPoint.Mount();
        _mounts.Add(mountPoint);

        _mounts = _mounts.OrderBy(mount => mount.Order).ToList();
    }

    /// <summary>
    /// Check if file exists or not.
    /// </summary>
    /// <param name="path">Relative path to the file.</param>
    /// <returns></returns>
    public static bool FileExists(string path)
    {
        return _mounts.Any(mount => mount.HasFile(path));
    }

    /// <summary>
    /// Gets a <see cref="VirtualFile"/> from path.
    /// </summary>
    /// <param name="path">Relative path to the file.</param>
    /// <returns>A virtual file at the path.</returns>
    public static VirtualFile GetFile(string path)
    {
        var mount = _mounts.FirstOrDefault(mount => mount.HasFile(path));
        if (mount == null)
        {
            throw new FileNotFoundException($"File \"{path}\" was not found in any mounted point.");
        }

        return mount.GetFile(path);
    }

    /// <summary>
    /// Reads a file.
    /// </summary>
    /// <param name="path">Relative path to the file.</param>
    /// <returns>A readable stream.</returns>
    public static Stream Read(string path)
    {
        var file = GetFile(path);
        return file.GetStream();
    }

    private static List<IVirtualMountPoint> _mounts = new();
}