// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@available(added=7)
library fuchsia.io.test;

using fuchsia.mem;
using fuchsia.io;
using zx;

// TODO(fxbug.dev/33880): Implement full testing framework. For now, we are
// hard-coding the desired directory layout manually in separate "Get"
// functions. In the next step, we would want to have a protocol to describe
// the intended directory layout setup, and integrate io2 connections.

/// Conformance test harnesses will implement this protocol to setup its
/// associated filesystem servers with the described directory layout,
/// allowing their implementation of `fuchsia.io` and `fuchsia.io2` protocols
/// to be verified by a common test suite.
///
/// Different test cases will not interact with one another during the
/// conformance test, and only one test case will be active at a time per
/// tested filesystem. So it is possible to host all cases as different
/// sub-directories under a common filesystem instance, to simplify the
/// lifecycle and implementation.
///
/// If a test case has mutable bits, each method call should be implemented
/// to obtain the directory in its original state. In other words, repeated
/// test case set up should "as-if" yield new directories.
///
/// See `src/storage/conformance/README.md` for an overview of io conformance
/// testing.
///
/// `Io1Config` lets the test harness modulate the set of expected outcomes and
/// behaviors validated by the test suite, by declaring specific properties
/// about the filesystem implementation. For example, setting [`ImmutableFile`]
/// to true informs the test suites that files hosted by this harness do not
/// support mutation.
type Io1Config = table {
    /// Files are mutable (i.e. support RIGHT_WRITABLE).
    1: mutable_file bool;

    /// Directories support the CREATE flag for creating new files.
    2: supports_create bool;

    /// ExecutableFile objects are supported.
    3: supports_executable_file bool;

    /// VmoFile objects are supported.
    4: supports_vmo_file bool;

    /// Remote directories are supported.
    5: supports_remote_dir bool;

    /// GetBuffer is supported by VmoFile objects.
    6: supports_get_buffer bool;

    /// Rename is supported.
    7: supports_rename bool;

    /// Link is supported.
    8: supports_link bool;

    /// SetAttr is supported.
    9: supports_set_attr bool;

    /// GetToken is supported.
   10: supports_get_token bool;

    /// Path handling conforms to in-tree behavior.
    /// TODO(fxbug.dev/82672): Ensure all libraries are conformant and remove this option.
    /// Currently the only non-conformant implementation being tested is the SDK VFS.
   11: conformant_path_handling bool;

    /// Unlink is supported.
   12: supports_unlink bool;
};

/// Directory entries should support opening with any combination of read/write/execute rights.
type Directory = resource table {
    /// Name not required for root directory.
    1: name string;

    /// Nullable to sidestep recursion rules. Don't actually supply nulls.
    2: entries vector<DirectoryEntry:optional>;
};

/// Remote directory which forwards FIDL requests from the server to the specified directory.
type RemoteDirectory = resource table {
    /// Name not required for root directory.
    1: name string;

    /// Remote client to forward Directory requests to.
    2: remote_client client_end:fuchsia.io.Directory;
};

/// File object which supports reading, and if `mutable_file` is true, also supports writing.
///
/// As the conformance tests verify W^X enforcement, attempting to open a File with RIGHT_EXECUTABLE
/// should fail with ACCESS_DENIED if `mutable_file` is true.
///
/// If executable files are required, use ExecutableFile instead.
type File = table {
    1: name string;
    2: contents bytes;
};

/// Vmo-backed file object which supports opening as readable + writable.
///
/// Enabled via the `supports_vmo_file` configuration option.
///
/// As the conformance tests verify W^X enforcement, attempting to open a VmoFile as executable
/// should fail with ACCESS_DENIED. If executable files are required, use ExecutableFile.
type VmoFile = resource table {
    1: name string;
    2: buffer fuchsia.mem.Range;
};

/// Adds an executable file that supports opening as readable + executable. The file has a non-zero
/// size, but the contents are otherwise unspecified.
///
/// Enabled by setting `supports_executable_file` to false. If enabled, `supports_get_buffer` should
/// be enabled to validate the permissions of the VMO backing the ExecutableFile.
///
/// As the conformance tests verify W^X enforcement, opening an ExecutableFile with RIGHT_WRITABLE
/// should fail with ACCESS_DENIED. If writable files are required, use File/VmoFile instead.
type ExecutableFile = table {
    1: name string;
};

type DirectoryEntry = strict resource union {
    1: directory Directory;
    2: remote_directory RemoteDirectory;
    3: file File;
    4: vmo_file VmoFile;
    5: executable_file ExecutableFile;
};

@discoverable
protocol Io1Harness {
    /// Returns the list of properties of the filesystem.
    GetConfig() -> (struct {
        config Io1Config;
    });

    /// Serves a directory with the given contents.
    ///
    /// `root` describes the initial layout of the filesystem that will be
    /// used for the test case. The root directory that is served (returned via
    /// `directory_request`) will have the equivalent contents, served with the
    /// given `flags`.
    GetDirectory(resource struct {
        root Directory;
        flags fuchsia.io.OpenFlags;
        directory_request server_end:fuchsia.io.Directory;
    });
};

/// Stub harness api for the io2.fidl protocol.
/// TODO(fxbug.dev/46082): Add separate io2 test harness api once we come up with a
/// good enough set of functions that we have enough flexibility to create
/// variable directory structures to with explicit permission settings for tests.
@discoverable
protocol Io2Harness {
    /// Prepares a test case with an empty directory. The directory metadata
    /// and directory entires should be read-only.
    ///
    /// + `directory_request` the server end of the root directory connection.
    ///
    /// This connection should have the following rights:
    ///
    ///     * [`fuchsia.io/Rights.CONNECT`].
    ///     * [`fuchsia.io/Rights.ENUMERATE`].
    ///     * [`fuchsia.io/Rights.TRAVERSE`].
    ///     * [`fuchsia.io/Rights.READ_BYTES`].
    ///     * [`fuchsia.io/Rights.WRITE_BYTES`].
    ///     * [`fuchsia.io/Rights.GET_ATTRIBUTES`].
    ///     * [`fuchsia.io/Rights.UPDATE_ATTRIBUTES`].
    ///
    GetEmptyDirectory(resource struct {
        directory_request zx.handle:CHANNEL;
    });
};
