// 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.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.
enum LogLevelFilter : int8 {
    [Deprecated = "Use NONE instead"]
    DEPRECATED_NONE = -1;
    [Deprecated = "Use INFO instead"]
    DEPRECATED_INFO = 0;
    [Deprecated = "Use WARN instead"]
    DEPRECATED_WARN = 1;
    [Deprecated = "Use ERROR instead"]
    DEPRECATED_ERROR = 2;
    [Deprecated = "Use FATAL instead"]
    DEPRECATED_FATAL = 3;
    ALL = -0x7F;
    TRACE = 0x10;
    DEBUG = 0x20;
    INFO = 0x30;
    WARN = 0x40;
    ERROR = 0x50;
    FATAL = 0x60;
    NONE = 0x7F;
};

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

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

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

/// Default log level used to initialize loggers.
const uint8 LOG_LEVEL_DEFAULT = 0x30; // LogLevel.INFO

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

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

/// A placeholder tag which indicates to a `LogSink` that the tag should be replaced with
/// the actual name of the logging component. If that name is unavailable, `LogSink`
/// implementations should replace this value with `UNKNOWN`.
const string COMPONENT_NAME_PLACEHOLDER_TAG = "COMPONENT_NAME";

struct LogFilterOptions {
    bool filter_by_pid;
    uint64 pid;

    bool filter_by_tid;
    uint64 tid;

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

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

    /// 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.
    vector<string:MAX_TAG_LEN_BYTES>:MAX_TAGS tags;
};

/// Max number of LogInterestSelectors that can be specified via a listener.
const uint8 MAX_LOG_SELECTORS = 5;

/// Conveyance to couple a specified Interest with it's designated target,
/// specified via a ComponentSelector.
struct LogInterestSelector {
    fuchsia.diagnostics.ComponentSelector selector;
    fuchsia.diagnostics.Interest interest;
};

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

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

struct LogMessage {
    uint64 pid;
    uint64 tid;
    /// https://fuchsia.dev/fuchsia-src/reference/syscalls/clock_get_monotonic.md
    zx.time time;
    int32 severity;

    /// See //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.
    uint32 dropped_logs;
    vector<string:MAX_TAG_LEN_BYTES>:MAX_TAGS_PER_LOG_MESSAGE tags;
    string:MAX_DATAGRAM_LEN_BYTES msg;
};

/// Interface for LogListenerSafe to register to listen to logs.
[Discoverable]
protocol Log {
    [Deprecated]
    Listen(LogListener log_listener, LogFilterOptions? options);

    [Deprecated]
    DumpLogs(LogListener log_listener, LogFilterOptions? options);

    /// 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.
    [Transitional]
    ListenSafe(LogListenerSafe log_listener, LogFilterOptions? options);

    /// Dumps all cached logs by calling LogMany() followed by Done() on `log_listener`.
    /// A null `options` indicates no filtering is requested.
    [Transitional]
    DumpLogsSafe(LogListenerSafe log_listener, LogFilterOptions? options);

    /// Listens to new log entries by calling Log() on `log_listener`.
    /// A null `options` indicates no filtering is requested.
    [Transitional]
    ListenSafeWithSelectors(LogListenerSafe log_listener, LogFilterOptions? options, vector<LogInterestSelector>:MAX_LOG_SELECTORS selectors);
};

/// Drains a program's logs.
[Discoverable]
protocol LogSink {
    /// Send this socket to be drained.
    ///
    /// See //zircon/system/ulib/syslog/include/lib/syslog/wire_format.h for what is expected to be
    /// received over the socket.
    Connect(zx.handle:SOCKET socket);

    /// Send this socket to be drained, using the structured logs format.
    ///
    /// See //docs/reference/diagnostics/logs/encoding.md for what is expected to be recieved over
    /// the socket.
    [Transitional]
    ConnectStructured(zx.handle:SOCKET socket);

    /// LogSink implementers emit this event 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
    /// (compile time) configuration.
    -> OnRegisterInterest(fuchsia.diagnostics.Interest interest);

    /// Use OnRegisterInterest instead.
    [Deprecated]
    -> OnInterestChanged(fuchsia.diagnostics.Interest interest);
};

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

/// Included temporarily for backwards compatiblity. Use `LogListenerSafe`.
[Deprecated]
protocol LogListener {
    Log(LogMessage log);
    LogMany(vector<LogMessage>:MAX log);
    Done();
};

/// A listener who will notify the `Log` of the receipt of each message.
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.
    Log(LogMessage log) -> ();

    /// 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.
    LogMany(vector<LogMessage>:MAX log) -> ();

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