// 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.testing;
using zx;
using fuchsia.testing.deadline;

/// Allows access to fake clocks managed by `FakeClockControl`.
@discoverable
protocol FakeClock {
    /// Gets the current time.
    Get() -> (struct {
        time zx.time;
    });
    /// Registers the event handle `event` to be signaled with `ZX_EVENTPAIR_SIGNALED` when the
    /// provided `time` is reached by the fake clock.
    /// The `FakeClock` instance will retain this event (even after it's fired) for as long as the
    /// client-side of the provided event pair `event` is open.
    RegisterEvent(resource struct {
        event zx.handle:EVENTPAIR;
        time zx.time;
    });
    /// Reschedules an event to be signalled with `ZX_EVENTPAIR_SIGNALED` at the new deadline in
    /// `time`.
    /// `event` is a duplicate of the client-side of the event pair, and it's used to retrieve the
    /// originally registered event through its kernel object identifier.
    RescheduleEvent(resource struct {
        event zx.handle:EVENTPAIR;
        time zx.time;
    }) -> ();
    /// Cancels a previously registered event.
    /// `event` is a duplicate of the client-side of the event pair, and it's used to retrieve the
    /// originally registered event through its kernel object identifier.
    CancelEvent(resource struct {
        event zx.handle:EVENTPAIR;
    }) -> ();
    /// Calculate and set a deadline associated with an id.
    /// The returned `deadline` is calculated as `duration` after the current fake time.
    /// FakeClock emits two events: A `SET` event immediately, and an `EXPIRED` event when the
    /// deadline expires. A test using `FakeClockControl` may reference events related to the
    /// deadline using a matching `id`. See `FakeClockControl.SetStopPoint` for information on how a
    /// test can wait for a deadline event.
    CreateNamedDeadline(struct {
        id fuchsia.testing.deadline.DeadlineId;
        duration zx.duration;
    }) -> (struct {
        deadline zx.time;
    });
};

/// The type of event related to a deadline.
type DeadlineEventType = strict enum {
    /// The deadline was set.
    SET = 1;
    /// The deadline has been reached.
    EXPIRED = 2;
};

/// A fake clock increment in a uniform random range.
type RandomRange = struct {
    /// The lower bound (inclusive) for the random duration.
    min_rand zx.duration;
    /// The upper bound (exclusive) for the random duration.
    max_rand zx.duration;
};

/// A fake clock increment step.
type Increment = strict union {
    /// Increments the fake clock by the `determined` duration.
    1: determined zx.duration;
    /// Increments the fake clock by a random duration chosen uniformly from the range in `random`.
    2: random RandomRange;
};

/// Provides control over fake clocks.
///
/// `FakeClockControl` provides complete control of the fake clocks that it provides, and serves
/// over `FakeClock`.
///
/// Upon start up, all the clocks are set to free-running with increments set to 1ms:1ms (same as
/// calling `SetIncrements` with a `real` duration of 1ms and a `determined` `increment` of 1ms as
/// well).
///
/// The initial time value for every fake clock is read from the corresponding real clock at start
/// up.
@discoverable
protocol FakeClockControl {
    /// Advances the fake clock `increment` once.
    /// Returns `ZX_ERR_INVALID_ARGS` if the provided `increment` is invalid (such as a badly formed
    /// RandomRange). Returns `ZX_ERR_ACCESS_DENIED` if called while the FakeClock is free-running.
    Advance(struct {
        increment Increment;
    }) -> (struct {}) error zx.status;
    /// Resumes free-running increments on the fake clock.
    /// `real` is the period based on the real monotonic clock over which `increment` is going to be
    /// applied. Returns `ZX_ERR_INVALID_ARGS` if the provided `increment` is invalid (such as a
    /// badly formed RandomRange).
    ResumeWithIncrements(struct {
        real zx.duration;
        increment Increment;
    }) -> (struct {}) error zx.status;
    /// Registers interest in a deadline event.
    /// `deadline_id` and `event_type` identify the named deadline and the event associated with
    /// the deadline. When the event occurs, FakeClock will signal `EVENTPAIR_SIGNALED` on
    /// `on_stop`. If time is free-running, the clock is stopped. Closing the eventpair cancels
    /// interest in the deadline. If the eventpair is closed when a deadline is reached, time is
    /// not stopped. Note that only events that occur after `AddStopPoint` is called are matched.
    /// In addition, the `EXPIRED` event is always reported, even if the component that created the
    /// deadline does not act on the deadline expiration.
    ///
    /// The intended use is to set a stop point using `AddStopPoint`, resume running time with
    /// `ResumeWithIncrements`, then wait for the stop point to occur using the `on_stop`
    /// eventpair.
    /// Setting a stop point is only allowed while time is stopped. If time is free running when
    /// this method is invoked `ZX_ERR_ACCESS_DENIED` is returned. If a stop point is already
    /// registered for the same event, `ZX_ALREADY_BOUND` is returned.
    AddStopPoint(resource struct {
        deadline_id fuchsia.testing.deadline.DeadlineId;
        event_type DeadlineEventType;
        on_stop zx.handle:EVENTPAIR;
    }) -> (struct {}) error zx.status;
    /// Pauses free-running increments on the fake clock.
    Pause() -> ();
};
