// Copyright 2021 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.fuzzer;

using fuchsia.url;
using zx;

/// Entry point for users, e.g. `ffx fuzz`, used to start and stop fuzzers. A
/// fuzzer will be started on the first call to `Connect` with a given URL.
/// Closing the given `Controller` channel does *not* stop the associated
/// fuzzer. Instead, since fuzzing is meant to be long-running, clients
/// may drop the connection and re-`Connect` some time later.
@discoverable
closed protocol Manager {
    /// Connects to a fuzzer that implements the `fuchsia.fuzzer/Controller`
    /// protocol.
    ///
    /// If the fuzzer is not currently running, the `fuzz_manager` will first
    /// start it (via the test_manager) before proceeding. The `fuzz_manager`
    /// sends the `controller` on to the fuzz-registry, which contains the
    /// `ControllerProviders` that can fulfill the connection request.
    ///
    /// See `fuchsia.test.manager/LaunchError` for details on ways
    /// `test_manager` can fail.
    ///
    /// + request `fuzzer_url` the package URL for the fuzzer.
    /// + request `controller` the connection from the client.
    /// * error one of the following:
    ///     * `ZX_ERR_NO_RESOURCES` if `test_manager` needs resources that are
    ///       unavailable.
    ///     * `ZX_ERR_NOT_FOUND` if the fuzzer URL is not recognized by
    ///       `test_manager`.
    ///     * `ZX_ERR_INVALID_ARGS` if `test_manager` reports invalid arguments.
    ///     * `ZX_ERR_NOT_SUPPORTED` if `test_manager` cannot connect to the
    ///       test suite.
    ///     * `ZX_ERR_INTERNAL` if `test_manager` encountered some other,
    ///       unspecified failure.
    ///     * `ZX_ERR_TIMED_OUT` if the fuzzer is not present or added to
    ///       fuzz-registry after starting.
    ///     * `ZX_ERR_SHOULD_WAIT` if another fuzzer is still starting.
    strict Connect(resource struct {
        fuzzer_url fuchsia.url.Url;
        controller server_end:Controller;
    }) -> () error zx.Status;

    /// Forwards the fuzzer's output of the given type to the provided socket.
    ///
    /// If this method is called multiple times for the same output type, the
    /// socket from the subsequent call replaces the socket from the earlier
    /// call, which is closed.
    ///
    /// + request `fuzzer_url` the package URL for the fuzzer.
    /// + request `output` the type of the output stream to forward.
    /// + request `socket` a socket to forward the output stream to.
    /// * error one of the following:
    ///     * `ZX_ERR_INVALID_ARGS` if the URL cannot be parsed.
    ///     * `ZX_ERR_NOT_FOUND` if the fuzzer URL was not recognized by
    ///       `test_manager`.
    ///     * `ZX_ERR_BAD_STATE` if the fuzzer is not connected.
    strict GetOutput(resource struct {
        fuzzer_url fuchsia.url.Url;
        output TestOutput;
        socket zx.Handle:SOCKET;
    }) -> () error zx.Status;

    /// Stops the associated fuzzer immediately, ending any workflows in
    /// progress.
    ///
    /// + request `fuzzer_url` the package URL for the fuzzer.
    /// * error `ZX_ERR_NOT_FOUND` if no fuzzer was active with the given URL.
    strict Stop(struct {
        fuzzer_url fuchsia.url.Url;
    }) -> () error zx.Status;
};

/// Represents types of fuzzer output.
///
/// These correspond to the subset of the `fuchsia.test_manager/Artifact`s that
/// `fuzz_manager` can forward. The name "artifact" is avoided due to its
/// distinct meaning for fuzzers; namely, `fuchsia.fuzzer.Artifact`.
type TestOutput = flexible enum {
    /// Standard output from fuzzer.
    STDOUT = 1;

    /// Standard error from fuzzer.
    STDERR = 2;

    /// System logs from fuzzer.
    SYSLOG = 3;
};

/// Command line flag requesting fuzzing to be performed.
///
/// This flag is passed by the `fuzz_manager` to the `test_manager` when
/// starting fuzzers. Since the fuzzers are run as part of the Test Runner
/// Framework, they can be started by normal test workflows, e.g. `fx test`. The
/// presence of this flag indicates the fuzzer is being started to perform
/// fuzzing; in its absence the fuzzer should simply execute a bounded number of
/// inputs as a test.
const FUZZ_MODE string = "--fuzz";
