// 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.io;
using zx;

// TODO(https://fxbug.dev/42109125): 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 = struct {
    /// ExecutableFile objects are supported.
    supports_executable_file bool;

    /// GetBackingMemory is supported.
    supports_get_backing_memory bool;

    /// Remote directories are supported.
    supports_remote_dir bool;

    /// GetToken is supported.
    supports_get_token bool;

    /// Supports fuchsia.io's Open2 method.
    supports_open2 bool;

    /// Supports fuchsia.io's LinkInto method.
    supports_link_into bool;

    /// Files can be opened in append mode.
    supports_append bool;

    /// The set of attributes the filesystem supports. If mutable attributes are reported, the
    /// harness must support [`fuchsia.io/Node.SetAttr`] and [`fuchsia.io/Node.UpdateAttributes`].
    supported_attributes fuchsia.io.NodeAttributesQuery;

    /// Directories support creating files, Rename, Link, and Unlink.
    supports_modify_directory bool;
};

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

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

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

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

/// File object which supports reading and writing.
///
/// As the conformance tests verify W^X enforcement, attempting to open a File with RIGHT_EXECUTABLE
/// should fail with ACCESS_DENIED.
///
/// If executable files are required, use ExecutableFile instead.
type File = struct {
    name string;
    contents vector<uint8>:MAX;
};

/// Adds an executable file that supports opening as readable + executable. The file has a non-zero
/// size, but the contents are otherwise unspecified.
///
/// Enabled via the `supports_executable_file` configuration option. `ExecutableFile` objects should
/// support fuchsia.io/File.GetBackingMemory.
///
/// 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 instead.
type ExecutableFile = struct {
    name string;
};

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

@discoverable
closed protocol Io1Harness {
    /// Returns the list of properties of the filesystem.
    strict 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`.
    strict 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(https://fxbug.dev/42122678): 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
closed 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`].
    ///
    strict GetEmptyDirectory(resource struct {
        directory_request zx.Handle:CHANNEL;
    });
};
