// 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.

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.
table Io1Config {
    /// Files are read-only.
    1: bool immutable_file;

    /// Directories are read-only.
    2: bool immutable_dir;

    /// The exec rights is not supported.
    3: bool no_exec;

    /// Vmofiles are not supported.
    4: bool no_vmofile;

    /// Remote directories are not supported.
    5: bool no_remote_dir;
};

resource table Directory {
    /// Name not required for root directory.
    1: string name;

    /// fuchsia.io OPEN_RIGHT_* flags for the directory.
    2: uint32 flags;

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

table File {
    1: string name;

    /// fuchsia.io OPEN_RIGHT_* flags for the file.
    2: uint32 flags;

    3: bytes contents;
};

resource table VmoFile {
    1: string name;

    /// fuchsia.io OPEN_RIGHT_* flags for the VMO file.
    2: uint32 flags;

    3: fuchsia.mem.Range buffer;
};

resource union DirectoryEntry {
    1: Directory directory;
    2: File file;
    3: VmoFile vmo_file;
};

[Discoverable]
protocol Io1Harness {
    /// Returns the list of properties of the filesystem.
    GetConfig() -> (Io1Config config);

    /// 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.
    GetDirectory(Directory root,
                 request<fuchsia.io.Directory> directory_request);

    /// Serves a directory with a single vmofile inside.
    ///
    /// + `name` the name of the vmofile in the root directory.
    /// + `flags` the flags the served directory connection has.
    /// + `directory_request` the server end of the root directory connection.
    ///
    /// TODO(fxbug.dev/33880): Add suppport for VMO files to GetDirectory and
    /// then delete this method.
    GetDirectoryWithVmoFile(fuchsia.mem.Range file,
                            string name,
                            uint32 flags,
                            request<fuchsia.io.Directory> directory_request);

    /// Serves a directory that holds a child `remote_directory` with name
    /// `dir_name`. The `directory_request` connection to the root directory
    /// has rights defined by `flags`.
    /// Note: This might not actually be needed for the defined io1 tests, but
    /// still might be useful for future testing if a fs forwards the correct
    /// request to the remote.
    ///
    /// + `remote_directory` the client end of the child remote directory.
    /// + `name` the name of the child remote directory in the root directory.
    /// + `flags` the flags the served directory connection has.
    /// + `directory_request` the server end of the root directory connection.
    ///
    /// TODO(fxbug.dev/33880): Add suppport for remote directories to
    /// GetDirectory and then delete this method.
    GetDirectoryWithRemoteDirectory(fuchsia.io.Directory remote_directory,
                                    string name,
                                    uint32 flags,
                                    request<fuchsia.io.Directory> directory_request);
};

/// 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.io2/Rights.CONNECT`].
    ///     * [`fuchsia.io2/Rights.ENUMERATE`].
    ///     * [`fuchsia.io2/Rights.TRAVERSE`].
    ///     * [`fuchsia.io2/Rights.READ_BYTES`].
    ///     * [`fuchsia.io2/Rights.WRITE_BYTES`].
    ///     * [`fuchsia.io2/Rights.GET_ATTRIBUTES`].
    ///     * [`fuchsia.io2/Rights.UPDATE_ATTRIBUTES`].
    ///
    GetEmptyDirectory(zx.handle:CHANNEL directory_request);
};
