// 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.
@available(added=7)
library fuchsia.logger;

using zx;
using fuchsia.diagnostics;

/// Log levels used with log related filtering.
/// Filtering uses a heuristic based on a threshold of
/// minimum severity level - with any log equal to or
/// greater than the threshold being included in the
/// printable logs.
// TODO(fxbug.dev/104630): Change this from `strict` to `flexible` #strictaudit
type LogLevelFilter = strict enum : int8 {
    @available(removed=8)
    DEPRECATED_INFO_LOAD_BEARING_IN_CHROMIUM = 0;
    TRACE = 0x10;
    DEBUG = 0x20;
    INFO = 0x30;
    WARN = 0x40;
    ERROR = 0x50;
    FATAL = 0x60;
    NONE = 0x7F;
};

/// The interval between discrete log severity levels
const LOG_SEVERITY_STEP_SIZE uint8 = 0x10;

/// Maximum available log severity.
const LOG_SEVERITY_MAX_STEP uint8 = 6;

/// The interval between discrete log verbosity levels
const LOG_VERBOSITY_STEP_SIZE uint8 = 0x1;

/// Default log level used to initialize loggers.
const LOG_LEVEL_DEFAULT LogLevelFilter = LogLevelFilter.INFO;

/// Max number of tags that can be passed to filter by listener.
const MAX_TAGS uint8 = 16;

/// Max tag length that can be passed to filter by listener.
const MAX_TAG_LEN_BYTES uint8 = 63;

type LogFilterOptions = struct {
    filter_by_pid bool;
    pid uint64;

    filter_by_tid bool;
    tid uint64;

    /// If more than zero, logs would be filtered based on verbosity and
    /// `min_severity` would be ignored.
    verbosity uint8;

    /// Severity used as threshold to determine logging level.
    min_severity LogLevelFilter;

    /// If non-empty, return all messages which contain at least one specified
    /// tag.  If empty, messages will not be filtered by tag.
    /// Passed tags should not be more than `MAX_TAG_LEN_BYTES` bytes in length
    /// and max tags can be `MAX_TAGS`.
    /// Listener would be discarded if the limit is not followed.
    tags vector<string:MAX_TAG_LEN_BYTES>:MAX_TAGS;
};

/// Max tags that will be attached to a LogMessage.
const MAX_TAGS_PER_LOG_MESSAGE uint8 = 5;

/// Max byte size for message payload.
const MAX_DATAGRAM_LEN_BYTES uint32 = 32768;

type LogMessage = struct {
    pid uint64;
    tid uint64;
    /// [zx_clock_get_monotonic](https://fuchsia.dev/fuchsia-src/reference/syscalls/clock_get_monotonic.md)
    time zx.Time;
    severity int32;

    /// See [wire_format.h](https://cs.opensource.google/fuchsia/fuchsia/+/main:zircon/system/ulib/syslog/include/lib/syslog/wire_format.h).
    /// As messages can be served out of order, this should only be logged if more than
    /// last count.
    dropped_logs uint32;
    tags vector<string:MAX_TAG_LEN_BYTES>:MAX_TAGS_PER_LOG_MESSAGE;
    msg string:MAX_DATAGRAM_LEN_BYTES;
};

/// Interface for LogListenerSafe to register to listen to logs.
@discoverable
closed protocol Log {
    /// Dumps all cached logs by calling LogMany() in batches followed by Log() for each new log
    /// message.
    /// A null `options` indicates no filtering is requested.
    strict ListenSafe(resource struct {
        log_listener client_end:LogListenerSafe;
        options box<LogFilterOptions>;
    });

    /// Dumps all cached logs by calling LogMany() followed by Done() on `log_listener`.
    /// A null `options` indicates no filtering is requested.
    strict DumpLogsSafe(resource struct {
        log_listener client_end:LogListenerSafe;
        options box<LogFilterOptions>;
    });

    /// Listens to new log entries by calling Log() on `log_listener`.
    /// A null `options` indicates no filtering is requested.
    strict ListenSafeWithSelectors(resource struct {
        log_listener client_end:LogListenerSafe;
        options box<LogFilterOptions>;
        selectors
                vector<fuchsia.diagnostics.LogInterestSelector>:fuchsia.diagnostics.MAX_LOG_SELECTORS;
    });
};

// TODO(fxbug.dev/104630): Change this from `strict` to `flexible`. #strictaudit
type InterestChangeError = strict enum : uint32 {
    /// Incorrectly called WaitForInterestChange twice
    /// without waiting for the first call to return.
    CALLED_TWICE = 1;
};

/// Drains a program's logs.
@discoverable
closed protocol LogSink {
    /// Send this socket to be drained.
    ///
    /// See [wire_format.h](https://cs.opensource.google/fuchsia/fuchsia/+/main:zircon/system/ulib/syslog/include/lib/syslog/wire_format.h)
    /// for what is expected to be received over the socket.
    strict Connect(resource struct {
        socket zx.Handle:SOCKET;
    });

    /// LogSink implementers will return to this hanging-get whenever the scope of
    /// their interest changes. Clients are expected to emit messages based on
    /// the registered Interest. In the event that an empty interest is
    /// conveyed, clients should emit messages based on their default
    /// e.g. compile time configuration. Each client may only poll this once at a time.
    /// Invoking WaitForInterestChange a second time before the first call returns will
    /// result in an error being returned.
    strict WaitForInterestChange() -> (struct {
        data fuchsia.diagnostics.Interest;
    }) error InterestChangeError;

    /// Send this socket to be drained, using the structured logs format.
    ///
    /// See [Encoding structured records](https://fuchsia.dev/fuchsia-src/reference/platform-spec/diagnostics/logs-encoding)
    /// for what is expected to be received over the socket.
    strict ConnectStructured(resource struct {
        socket zx.Handle:SOCKET;
    });
};

/// Max log bytes per call to a listener.
const MAX_LOG_MANY_SIZE_BYTES uint64 = 16384;

/// A listener who will notify the `Log` of the receipt of each message.
closed protocol LogListenerSafe {
    /// Called for single messages.
    ///
    /// The return value is used for flow control, and implementers should acknowledge receipt of
    /// each message in order to continue receiving future messages.
    strict Log(struct {
        log LogMessage;
    }) -> ();

    /// Called when serving cached logs.
    ///
    /// Max logs size per call is `MAX_LOG_MANY_SIZE_BYTES` bytes.
    ///
    /// The return value is used for flow control, and implementers should acknowledge receipt of
    /// each batch in order to continue receiving future messages.
    strict LogMany(struct {
        log vector<LogMessage>:MAX;
    }) -> ();

    /// Called when this listener was passed to `DumpLogsSafe()` and all cached logs have been sent.
    strict Done();
};
