// Copyright 2018 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.netemul.environment;
using fuchsia.sys;
using fuchsia.netemul.network;
using fuchsia.logger;

/// A single service to be launched in managed environment.
struct LaunchService {
    /// Service name.
    string name;
    /// Service launch url (fuchsia component url).
    string url;
    /// Service launch arguments
    vector<string>? arguments;
};

/// A single virtual device to make available for child processes.
/// Virtual devices are mounted on /vdev.
struct VirtualDevice {
    /// Relative path to /vdev.
    string path;
    /// Virtual device server.
    fuchsia.netemul.network.DeviceProxy device;
};

/// Logger specific options for a created environment
table LoggerOptions {
    /// Enable printing logs.
    1: bool enabled;
    /// Enable kernel logs (no effect if `enabled` is false).
    2: bool klogs_enabled;
    /// LogFilter Options straight from fuchsia.logger.LogFilter.
    /// The LogFilterOptions will be passed directly to the `Listen`
    /// function of the fuchsia.logger.Log service without any
    /// modification. If none provided, assume null. See `Listen` of
    /// fuchsia.logger.Log for more information.
    3: fuchsia.logger.LogFilterOptions filter_options;
    /// Use the parent environment's syslog for output, only enriching
    /// tags with environment names. If false or not provided,
    /// environment logs are printed to stdout.
    4: bool syslog_output;
};

/// Options used to create environment.
table EnvironmentOptions {
    /// Environment name, for debugging purposes.
    /// If none provided, a random name will be generated.
    1: string name;
    /// Services to register on environment.
    /// If none provided, no additional services will be registered.
    /// However, a ManagedEnvironment may still register some default
    /// services.
    2: vector<LaunchService> services;
    /// Devices to make available.
    /// If none provided, no devices will be made available.
    3: vector<VirtualDevice> devices;
    /// Whether to inherit service launch options from parent environment.
    /// If none provided, assume false.
    4: bool inherit_parent_launch_services;
    /// Logger Options.
    /// If none provided, log printing is disabled by default.
    5: LoggerOptions logger_options;
};

/// Managed environment is made available on netemul runners.
/// Typically this interface will be used by the root runner
/// to setup the testing environment.
[Discoverable]
protocol ManagedEnvironment {
    /// Gets the managed launcher for the environment.
    GetLauncher(request<fuchsia.sys.Launcher> launcher);
    /// Creates a nested managed environment.
    CreateChildEnvironment(request<ManagedEnvironment> child_env, EnvironmentOptions options);
    /// Connects to a service named `name` provided by this environment.
    ConnectToService(string name, handle<channel> req);
    /// Exposes new virtual device `device` for all components within this environment
    AddDevice(VirtualDevice device);
    /// Removes virtual device mounted at `path` (relative to /vdev)
    RemoveDevice(string path);
};
