// 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 = table {
    /// Directories support the CREATE flag for creating new files.
    2: supports_create bool;

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

    /// GetBackingMemory is supported.
    4: supports_get_backing_memory bool;

    /// Remote directories are supported.
    5: supports_remote_dir 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;

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

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

    /// Supports fuchsia.io's GetAttributes method.
    14: supports_get_attributes bool;

    /// Supports fuchsia.io's UpdateAttributes method.
    15: supports_update_attributes bool;

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

    /// Supports directory watchers.
    17: supports_directory_watchers bool;

    /// Files can be opened in append mode.
    18: supports_append 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 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 = table {
    1: name string;
    2: 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 = table {
    1: 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;
    });
};
