// 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 MAX_EXCEPTIONS_PER_CALL uint64 = 32;

const MAX_FILTER_LENGTH uint64 = 32;
const MAX_FILTERS_PER_CALL uint64 = 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(struct {
        active bool;
    }) -> ();

    /// 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() -> (struct {
        is_active bool;
    });

    /// 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() -> (resource struct {
        exception_list vector<ProcessExceptionMetadata>:MAX_EXCEPTIONS_PER_CALL;
    }) 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(struct {
        process_koid zx.koid;
    }) -> (resource struct {
        process_exception ProcessException;
    }) 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(struct {
        process_koid zx.koid;
    }) -> (struct {}) 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(struct {
        filters vector<string:MAX_FILTER_LENGTH>:MAX_FILTERS_PER_CALL;
    }) -> (struct {}) 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(struct {
        filters vector<string:MAX_FILTER_LENGTH>:MAX_FILTERS_PER_CALL;
    }) -> (struct {}) error zx.status;

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

/// 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.
type ProcessExceptionMetadata = resource table {
    1: info ExceptionInfo;

    /// Only has ZX_RIGHT_READ and ZX_RIGHT_GET_PROPERTY rights.
    2: process zx.handle: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: thread zx.handle:THREAD;
};
