// 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.metrics.test;

using fuchsia.metrics as metrics;

/// Maximum number of events returned by a query.
const uint16 MAX_QUERY_LENGTH = 64;

/// This is currently not exhaustive.
enum LogMethod {
    LOG_OCCURRENCE = 1;
    LOG_INTEGER = 2;
    LOG_INTEGER_HISTOGRAM = 3;
    LOG_STRING = 4;
    LOG_METRIC_EVENTS = 5;
};

/// LoggerQuerier provides a way to query mock metrics services to check that
/// clients of metrics are logging events as expected.
[Discoverable]
protocol MetricEventLoggerQuerier {
    /// Returns the _first_ N events that were logged for the logger with the
    /// given `project_id` and a `more` flag indicating whether there were
    /// more than N events logged. There is no way to retrieve events logged
    /// after the first N events.
    ///
    /// Will hang until at least one metrics metric is recorded for the given
    /// `project_id` and `method`.
    ///
    /// Repeated calls to WatchLogs for a given LogMethod will block until new
    /// events are logged with that method, enabling tests to synchronize
    /// without sleeps or timeouts.
    WatchLogs(uint32 project_id, LogMethod method) -> (vector<metrics.MetricEvent>:MAX_QUERY_LENGTH events, bool more);

    /// Clear all logged events by logging `method` for the logger with the
    /// given `project_id`.
    ///
    /// This is a no-op if a logger for the given `project_id` does not exist.
    /// Notably, it does _not_ create a new logger with `project_id` if one
    /// does not already exist.
    ResetLogger(uint32 project_id, LogMethod method);
};
