// Copyright 2019 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.exception;

using zx;

/// The maximum amount of exceptions that will be listed at any given time by a
/// call to `ListProcessesWaitingOnException`.
const uint64 MAX_EXCEPTIONS_PER_CALL = 32;

const uint64 MAX_FILTER_LENGTH = 32;
const uint64 MAX_FILTERS_PER_CALL = 32;

/// Protocol meant for clients interested in obtaining processes that are
/// suspended waiting for an exception handler (in limbo). This is the core
/// feature that enables Just In Time (JIT) debugging.
///
/// An example usage of this API would be having a debugger listen on limbo for
/// new processes. Then another component (eg. a CLI tool) could activate the
/// limbo, meaning that the system is now ready to capture crashing processes.
/// As the debugger got a notification that the limbo is now active, it can
/// correctly handle newly excepted processes and do its normal workflow.
[Discoverable]
protocol ProcessLimbo {
    /// Set the active state of the limbo. Will trigger the `WatchActive` event
    /// if there was a change, meaning that any listening components will receive
    /// a notification. This includes the caller of `SetActive`.
    ///
    /// When a limbo is inactive, there will not be any processes waiting on it,
    /// meaning that any waiting processes will be freed upon deactivating the
    /// limbo.
    SetActive(bool active) -> ();

    /// Watchs for changes determining whether the limbo is currently active,
    /// using a Hanging Get pattern. An active limbo could be empty (not have
    /// any processes waiting on an exception).
    /// When a limbo is inactive, there will not be any processes waiting on it.
    WatchActive() -> (bool is_active);

    /// Watch for processes that are waiting on exceptions, using a Hanging Get
    /// Pattern.
    ///
    /// Returns information on all the processes currently waiting on an exception.
    /// The information provided is intended to correctly identify an exception
    /// and determine whether the caller wants to actually handle it.
    /// To retrieve an exception, use the `GetException` call.
    ///
    /// Returns ZX_ERR_UNAVAILABLE if limbo is not active.
    /// Returns ZX_ERR_CANCELED if there was an outstanding call and the limbo
    /// becomes inactive.
    ///
    /// NOTE: The `process` and `thread` handle will only have the ZX_RIGHT_READ
    ///       right, so no modification will be able to be done on them.
    WatchProcessesWaitingOnException() -> (vector<ProcessExceptionMetadata>:MAX_EXCEPTIONS_PER_CALL exception_list) error zx.status;

    /// Removes the process from limbo and retrieves the exception handle and
    /// associated metadata from an exception.
    ///
    /// Use `ListProcessesWaitingOnException` to choose a `process_koid` from the
    /// list of available exceptions.
    ///
    /// Returns ZX_ERR_NOT_FOUND if the process is not waiting on an exception.
    /// Returns ZX_ERR_UNAVAILABLE if limbo is not active.
    RetrieveException(zx.koid process_koid) -> (ProcessException process_exception) error zx.status;

    /// Removes the process from limbo, releasing the exception. This will make
    /// it "bubble up" beyond the scope of of this limbo, making it
    /// unretrievable in the future from here.
    ReleaseProcess(zx.koid process_koid) -> () error zx.status;

    /// Adds filters to the limbo. Filters determine what processes the limbo
    /// will store when receiving an exception. Repeated filters will be
    /// ignored. Filters work by "filtering out" processes. It means that if a
    /// filter matches, that process won't get included.
    ///
    /// Filters work by substring matching. This means that a process name has
    /// to have the filter as a substring in order to match it. Example:
    ///
    /// Filter = "dev".
    /// Process = "process" won't match.
    /// Process = "devcoordinator" will match.
    ///
    /// Adding filters is transactional: either all of them go in, or none at
    /// all. The maximum amount of filters is determined by
    /// `MAX_FILTERS_PER_CALL`. If the maximum is exceeded, ZX_ERR_NO_RESOURCES
    /// is returned.
    ///
    /// Changing filters have no effect on processes that are currently waiting
    /// on an exception, but rather which future processes that will remain in
    /// the limbo.
    ///
    /// Returns ZX_ERR_UNAVAILABLE if limbo is not active.
    AppendFilters(vector<string:MAX_FILTER_LENGTH>:MAX_FILTERS_PER_CALL filters) -> () error zx.status;

    /// Removes filters to the limbo. Any filters that are not currently present
    /// on the limbo will be ignored.
    ///
    /// Returns ZX_ERR_UNAVAILABLE if limbo is not active.
    RemoveFilters(vector<string:MAX_FILTER_LENGTH>:MAX_FILTERS_PER_CALL filters) -> () error zx.status;

    /// Returns filters that are currently active within the limbo. If the limbo
    /// is inactive, it will return an empty vector.
    GetFilters() -> (vector<string:MAX_FILTER_LENGTH>:MAX_FILTERS_PER_CALL filters);
};

/// Intended to be read only metadada associated with an exception waiting in
/// limbo. The handles provided will only have read-only access to the resource,
/// so no modification can be done to them.
///
/// NOTE: Both `process` and `thread` will be valid if present.
resource table ProcessExceptionMetadata {
    1: ExceptionInfo info;

    /// Only has ZX_RIGHT_READ and ZX_RIGHT_GET_PROPERTY rights.
    2: zx.handle:PROCESS process;

    /// The thread that generated the exception.
    /// The process may have other threads that are not reflected here.
    /// Only has ZX_RIGHT_READ and ZX_RIGHT_GET_PROPERTY rights.
    3: zx.handle:THREAD thread;
};
