// 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.

//! Execution contexts.
//!
//! This module defines "context" traits, which allow code in this crate to be
//! written agnostic to their execution context.
//!
//! All of the code in this crate operates in terms of "events". When an event
//! occurs (for example, a packet is received, an application makes a request,
//! or a timer fires), a function is called to handle that event. In response to
//! that event, the code may wish to emit new events (for example, to send a
//! packet, to respond to an application request, or to install a new timer).
//! The traits in this module provide the ability to emit new events. For
//! example, if, in order to handle some event, we need the ability to install
//! new timers, then the function to handle that event would take a
//! [`TimerContext`] parameter, which it could use to install new timers.
//!
//! Structuring code this way allows us to write code which is agnostic to
//! execution context - a test fake or any number of possible "real-world"
//! implementations of these traits all appear as indistinguishable, opaque
//! trait implementations to our code.
//!
//! The benefits are deeper than this, though. Large units of code can be
//! subdivided into smaller units that view each other as "contexts". For
//! example, the ARP implementation in the [`crate::device::arp`] module defines
//! the [`ArpContext`] trait, which is an execution context for ARP operations.
//! It is implemented both by the test fakes in that module, and also by the
//! Ethernet device implementation in the [`crate::device::ethernet`] module.
//!
//! This subdivision of code into small units in turn enables modularity. If,
//! for example, the IP code sees transport layer protocols as execution
//! contexts, then customizing which transport layer protocols are supported is
//! just a matter of providing a different implementation of the transport layer
//! context traits (this isn't what we do today, but we may in the future).

use core::{convert::Infallible as Never, ffi::CStr, fmt::Debug, time::Duration};

use lock_order::Unlocked;

use packet::{BufferMut, Serializer};
use rand::{CryptoRng, RngCore};

use crate::{
    counters::Counter,
    marker::{BindingsContext, BindingsTypes},
    state::StackState,
    sync, Instant,
};

pub use netstack3_base::{
    ContextPair, CoreTimerContext, InstantBindingsTypes, InstantContext, NestedIntoCoreTimerCtx,
    TimerBindingsTypes, TimerContext2,
};

/// A marker trait indicating that the implementor is not the [`FakeCoreCtx`]
/// type found in test environments.
///
/// See [this issue] for details on why this is needed.
///
/// [`FakeCoreCtx`]: testutil::FakeCoreCtx
/// [this issue]: https://github.com/rust-lang/rust/issues/97811
pub(crate) trait NonTestCtxMarker {}

impl<BC: BindingsContext, L> NonTestCtxMarker for CoreCtx<'_, BC, L> {}

/// An [`InstantContext`] which stores a cached value for the current time.
///
/// `CachedInstantCtx`s are constructed via [`new_cached_instant_context`].
pub(crate) struct CachedInstantCtx<I>(I);

impl<I: Instant + 'static> InstantBindingsTypes for CachedInstantCtx<I> {
    type Instant = I;
}

impl<I: Instant + 'static> InstantContext for CachedInstantCtx<I> {
    fn now(&self) -> I {
        self.0.clone()
    }
}

/// Construct a new `CachedInstantCtx` from the current time.
///
/// This is a hack until we figure out a strategy for splitting context objects.
/// Currently, since most context methods take a `&mut self` argument, lifetimes
/// which don't need to conflict in principle - such as the lifetime of state
/// obtained mutably from [`StateContext`] and the lifetime required to call the
/// [`InstantContext::now`] method on the same object - do conflict, and thus
/// cannot overlap. Until we figure out an approach to deal with that problem,
/// this exists as a workaround.
pub(crate) fn new_cached_instant_context<I: InstantContext + ?Sized>(
    bindings_ctx: &I,
) -> CachedInstantCtx<I::Instant> {
    CachedInstantCtx(bindings_ctx.now())
}

/// A context that supports scheduling timers.
pub trait TimerContext<Id>: InstantContext {
    /// Schedule a timer to fire after some duration.
    ///
    /// `schedule_timer` schedules the given timer to be fired after `duration`
    /// has elapsed, overwriting any previous timer with the same ID.
    ///
    /// If there was previously a timer with that ID, return the time at which
    /// is was scheduled to fire.
    ///
    /// # Panics
    ///
    /// `schedule_timer` may panic if `duration` is large enough that
    /// `self.now() + duration` overflows.
    fn schedule_timer(&mut self, duration: Duration, id: Id) -> Option<Self::Instant> {
        self.schedule_timer_instant(self.now().checked_add(duration).unwrap(), id)
    }

    /// Schedule a timer to fire at some point in the future.
    ///
    /// `schedule_timer` schedules the given timer to be fired at `time`,
    /// overwriting any previous timer with the same ID.
    ///
    /// If there was previously a timer with that ID, return the time at which
    /// is was scheduled to fire.
    fn schedule_timer_instant(&mut self, time: Self::Instant, id: Id) -> Option<Self::Instant>;

    /// Cancel a timer.
    ///
    /// If a timer with the given ID exists, it is canceled and the instant at
    /// which it was scheduled to fire is returned.
    fn cancel_timer(&mut self, id: Id) -> Option<Self::Instant>;

    /// Cancel all timers which satisfy a predicate.
    ///
    /// `cancel_timers_with` calls `f` on each scheduled timer, and cancels any
    /// timer for which `f` returns true.
    fn cancel_timers_with<F: FnMut(&Id) -> bool>(&mut self, f: F);

    /// Get the instant a timer will fire, if one is scheduled.
    ///
    /// Returns the [`Instant`] a timer with ID `id` will be invoked. If no
    /// timer with the given ID exists, `scheduled_instant` will return `None`.
    fn scheduled_instant(&self, id: Id) -> Option<Self::Instant>;
}

/// A handler for timer firing events.
///
/// A `TimerHandler` is a type capable of handling the event of a timer firing.
pub trait TimerHandler<BC, Id> {
    /// Handle a timer firing.
    fn handle_timer(&mut self, bindings_ctx: &mut BC, id: Id);
}

// NOTE:
// - Code in this crate is required to only obtain random values through an
//   `RngContext`. This allows a deterministic RNG to be provided when useful
//   (for example, in tests).
// - The CSPRNG requirement exists so that random values produced within the
//   network stack are not predictable by outside observers. This helps prevent
//   certain kinds of fingerprinting and denial of service attacks.

/// A context that provides a random number generator (RNG).
pub trait RngContext {
    // TODO(joshlf): If the CSPRNG requirement becomes a performance problem,
    // introduce a second, non-cryptographically secure, RNG.

    /// The random number generator (RNG) provided by this `RngContext`.
    ///
    /// The provided RNG must be cryptographically secure, and users may rely on
    /// that property for their correctness and security.
    type Rng<'a>: RngCore + CryptoRng
    where
        Self: 'a;

    /// Gets the random number generator (RNG).
    fn rng(&mut self) -> Self::Rng<'_>;
}

/// A context for receiving frames.
pub trait RecvFrameContext<BC, Meta> {
    /// Receive a frame.
    ///
    /// `receive_frame` receives a frame with the given metadata.
    fn receive_frame<B: BufferMut + Debug>(
        &mut self,
        bindings_ctx: &mut BC,
        metadata: Meta,
        frame: B,
    );
}

/// Any type can implement a receive frame context with uninstantiable metadata.
impl<T, BC> RecvFrameContext<BC, Never> for T {
    fn receive_frame<B: BufferMut>(&mut self, _bindings_ctx: &mut BC, metadata: Never, _frame: B) {
        match metadata {}
    }
}

/// A context for sending frames.
pub trait SendFrameContext<BC, Meta> {
    // TODO(joshlf): Add an error type parameter or associated type once we need
    // different kinds of errors.

    /// Send a frame.
    ///
    /// `send_frame` sends a frame with the given metadata. The frame itself is
    /// passed as a [`Serializer`] which `send_frame` is responsible for
    /// serializing. If serialization fails for any reason, the original,
    /// unmodified `Serializer` is returned.
    ///
    /// [`Serializer`]: packet::Serializer
    fn send_frame<S>(&mut self, bindings_ctx: &mut BC, metadata: Meta, frame: S) -> Result<(), S>
    where
        S: Serializer,
        S::Buffer: BufferMut;
}

/// A context that stores counters.
///
/// `CounterContext` exposes access to counters for observation and debugging.
pub trait CounterContext<T> {
    /// Call the function with an immutable reference to counter type T.
    fn with_counters<O, F: FnOnce(&T) -> O>(&self, cb: F) -> O;

    /// Increments the counter returned by the callback.
    fn increment<F: FnOnce(&T) -> &Counter>(&self, cb: F) {
        self.with_counters(|counters| cb(counters).increment());
    }
}

/// A context that provides access to per-resource counters for observation and
/// debugging.
pub trait ResourceCounterContext<R, T>: CounterContext<T> {
    /// Call `cb` with an immutable reference to the set of counters on `resource`.
    fn with_per_resource_counters<O, F: FnOnce(&T) -> O>(&mut self, resource: &R, cb: F) -> O;

    /// Increments both the per-resource and stackwide versions of
    /// the counter returned by the callback.
    fn increment<F: Fn(&T) -> &Counter>(&mut self, resource: &R, cb: F) {
        self.with_per_resource_counters(resource, |counters| cb(counters).increment());
        self.with_counters(|counters| cb(counters).increment());
    }
}

/// A context for emitting events.
///
/// `EventContext` encodes the common pattern for emitting atomic events of type
/// `T` from core. An implementation of `EventContext` must guarantee that
/// events are processed in the order they are emitted.
pub trait EventContext<T> {
    /// Handles `event`.
    fn on_event(&mut self, event: T);
}

/// A context for emitting tracing data.
pub trait TracingContext {
    /// The scope of a trace duration.
    ///
    /// Its lifetime corresponds to the beginning and end of the duration.
    type DurationScope;

    /// Writes a duration event which ends when the returned scope is dropped.
    ///
    /// Durations describe work which is happening synchronously on one thread.
    /// Care should be taken to avoid a duration's scope spanning an `await`
    /// point in asynchronous code.
    fn duration(&self, name: &'static CStr) -> Self::DurationScope;
}

/// A context trait determining the types to be used for reference notifications.
pub trait ReferenceNotifiers {
    /// The receiver for shared reference destruction notifications.
    type ReferenceReceiver<T: 'static>: 'static;
    /// The notifier for shared reference destruction notifications.
    type ReferenceNotifier<T: Send + 'static>: sync::RcNotifier<T> + 'static;

    /// Creates a new Notifier/Receiver pair for `T`.
    ///
    /// `debug_references` is given to provide information on outstanding
    /// references that caused the notifier to be requested.
    fn new_reference_notifier<T: Send + 'static, D: Debug>(
        debug_references: D,
    ) -> (Self::ReferenceNotifier<T>, Self::ReferenceReceiver<T>);
}

/// Provides access to core context implementations.
///
/// `L` is the current lock level of `CoreCtx`. The alias [`UnlockedCoreCtx`] is
/// provided at the [`Unlocked`] level.
pub type CoreCtx<'a, BT, L> = Locked<&'a StackState<BT>, L>;

pub(crate) type CoreCtxAndResource<'a, BT, R, L> =
    Locked<lock_order::OwnedTupleWrapper<&'a StackState<BT>, &'a R>, L>;

/// An alias for an unlocked [`CoreCtx`].
pub type UnlockedCoreCtx<'a, BT> = CoreCtx<'a, BT, Unlocked>;

pub(crate) use locked::Locked;

/// A type that provides a context implementation.
///
/// This trait allows for [`CtxPair`] to hold context implementations
/// agnostically of the storage method and how they're implemented. For example,
/// tests usually create API structs with a mutable borrow to contexts, while
/// the core context exposed to bindings is implemented on an owned [`CoreCtx`]
/// type.
///
/// The shape of this trait is equivalent to [`core::ops::DerefMut`] but we
/// decide against using that because of the automatic dereferencing semantics
/// the compiler provides around implementers of `DerefMut`.
pub trait ContextProvider {
    /// The context provided by this `ContextProvider`.
    type Context: Sized;

    /// Gets a mutable borrow to this context.
    fn context(&mut self) -> &mut Self::Context;
}

impl<'a, T: Sized> ContextProvider for &'a mut T {
    type Context = T;

    fn context(&mut self) -> &mut Self::Context {
        &mut *self
    }
}

impl<'a, BT, L> ContextProvider for CoreCtx<'a, BT, L>
where
    BT: BindingsTypes,
{
    type Context = Self;

    fn context(&mut self) -> &mut Self::Context {
        self
    }
}

/// A concrete implementation of [`ContextPair`].
///
///
/// `CtxPair` provides a [`ContextPair`] implementation when `CC` and `BC` are
/// [`ContextProvider`] and using their respective targets as the `CoreContext`
/// and `BindingsContext` associated types.
pub struct CtxPair<CC, BC> {
    pub(crate) core_ctx: CC,
    pub(crate) bindings_ctx: BC,
}

impl<CC, BC> ContextPair for CtxPair<CC, BC>
where
    CC: ContextProvider,
    BC: ContextProvider,
{
    type CoreContext = CC::Context;
    type BindingsContext = BC::Context;

    fn contexts(&mut self) -> (&mut Self::CoreContext, &mut Self::BindingsContext) {
        let Self { core_ctx, bindings_ctx } = self;
        (core_ctx.context(), bindings_ctx.context())
    }
}

/// Provides a crate-local wrapper for `[lock_order::Locked]`.
///
/// This module is intentionally private so usage is limited to the type alias
/// in [`CoreCtx`].
mod locked {
    use super::{BindingsTypes, CoreCtx, StackState};

    use core::ops::Deref;
    use lock_order::{wrap::LockedWrapper, Locked as ExternalLocked, TupleWrapper, Unlocked};

    /// A crate-local wrapper on [`lock_order::Locked`].
    pub struct Locked<T, L>(ExternalLocked<T, L>);

    impl<T, L> LockedWrapper<T, L> for Locked<T, L>
    where
        T: Deref,
        T::Target: Sized,
    {
        type AtLockLevel<'l, M> = Locked<&'l T::Target, M>
    where
        M: 'l,
        T: 'l;

        type CastWrapper<X> = Locked<X, L>
    where
        X: Deref,
        X::Target: Sized;

        fn wrap<'l, M>(locked: ExternalLocked<&'l T::Target, M>) -> Self::AtLockLevel<'l, M>
        where
            M: 'l,
            T: 'l,
        {
            Locked(locked)
        }

        fn wrap_cast<R: Deref>(locked: ExternalLocked<R, L>) -> Self::CastWrapper<R>
        where
            R::Target: Sized,
        {
            Locked(locked)
        }

        fn get_mut(&mut self) -> &mut ExternalLocked<T, L> {
            let Self(locked) = self;
            locked
        }

        fn get(&self) -> &ExternalLocked<T, L> {
            let Self(locked) = self;
            locked
        }
    }

    impl<'a, BT: BindingsTypes> CoreCtx<'a, BT, Unlocked> {
        /// Creates a new `CoreCtx` from a borrowed [`StackState`].
        pub fn new(stack_state: &'a StackState<BT>) -> Self {
            Self(ExternalLocked::new(stack_state))
        }
    }

    impl<'a, BT, R, L, T> Locked<T, L>
    where
        R: 'a,
        T: Deref<Target = TupleWrapper<&'a StackState<BT>, &'a R>>,
        BT: BindingsTypes,
    {
        pub(crate) fn cast_resource(&mut self) -> Locked<&'_ R, L> {
            let Self(locked) = self;
            Locked(locked.cast_with(|c| c.right()))
        }

        pub(crate) fn cast_core_ctx(&mut self) -> CoreCtx<'_, BT, L> {
            let Self(locked) = self;
            crate::CoreCtx::<BT, L>::wrap(locked.cast_with(|c| c.left()))
        }
    }
}

/// Fake implementations of context traits.
///
/// Each trait `Xxx` has a fake called `FakeXxx`. `FakeXxx` implements `Xxx`,
/// and `impl<T> FakeXxx for T` where either `T: AsRef<FakeXxx>` or `T:
/// AsMut<FakeXxx>` or both (depending on the trait). This allows fake
/// implementations to be composed easily - any container type need only provide
/// the appropriate `AsRef` and/or `AsMut` implementations, and the blanket impl
/// will take care of the rest.
#[cfg(any(test, feature = "testutils"))]
pub(crate) mod testutil {
    use alloc::{boxed::Box, collections::BinaryHeap, format, string::String, sync::Arc, vec::Vec};
    #[cfg(test)]
    use alloc::{collections::HashMap, vec};
    use core::{convert::Infallible as Never, fmt::Debug, hash::Hash};
    #[cfg(test)]
    use core::{marker::PhantomData, ops};

    #[cfg(test)]
    use assert_matches::assert_matches;
    use derivative::Derivative;

    use net_types::ip::IpVersion;

    #[cfg(test)]
    use packet::Buf;
    use rand_xorshift::XorShiftRng;

    use super::*;
    use crate::{
        data_structures::ref_counted_hash_map::{RefCountedHashSet, RemoveResult},
        device::{link::LinkDevice, pure_ip::PureIpWeakDeviceId, DeviceLayerTypes},
        filter::FilterBindingsTypes,
        ip::device::nud::{LinkResolutionContext, LinkResolutionNotifier},
        sync::Mutex,
        testutil::FakeCryptoRng,
    };
    #[cfg(test)]
    use crate::{
        device::{EthernetDeviceId, EthernetWeakDeviceId},
        filter::FilterHandlerProvider,
        testutil::DispatchedFrame,
    };

    pub use netstack3_base::testutil::{FakeInstant, FakeInstantCtx};

    /// Arbitrary data of type `D` attached to a `FakeInstant`.
    ///
    /// `InstantAndData` implements `Ord` and `Eq` to be used in a `BinaryHeap`
    /// and ordered by `FakeInstant`.
    #[derive(Clone, Debug)]
    pub(crate) struct InstantAndData<D>(pub(crate) FakeInstant, pub(crate) D);

    impl<D> InstantAndData<D> {
        pub(crate) fn new(time: FakeInstant, data: D) -> Self {
            Self(time, data)
        }
    }

    impl<D> Eq for InstantAndData<D> {}

    impl<D> PartialEq for InstantAndData<D> {
        fn eq(&self, other: &Self) -> bool {
            self.0 == other.0
        }
    }

    impl<D> Ord for InstantAndData<D> {
        fn cmp(&self, other: &Self) -> core::cmp::Ordering {
            other.0.cmp(&self.0)
        }
    }

    impl<D> PartialOrd for InstantAndData<D> {
        fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
            Some(self.cmp(other))
        }
    }

    /// A fake [`TimerContext`] which stores time as a [`FakeInstantCtx`].
    pub(crate) struct FakeTimerCtx<Id> {
        pub(crate) instant: FakeInstantCtx,
        timers: BinaryHeap<InstantAndData<Id>>,
    }

    impl<Id> Default for FakeTimerCtx<Id> {
        fn default() -> FakeTimerCtx<Id> {
            FakeTimerCtx { instant: FakeInstantCtx::default(), timers: BinaryHeap::default() }
        }
    }

    impl<Id> AsMut<FakeTimerCtx<Id>> for FakeTimerCtx<Id> {
        fn as_mut(&mut self) -> &mut FakeTimerCtx<Id> {
            self
        }
    }

    impl<Id: Clone> FakeTimerCtx<Id> {
        /// Get an ordered list of all currently-scheduled timers.
        #[cfg(test)]
        pub(crate) fn timers(&self) -> Vec<(FakeInstant, Id)> {
            self.timers
                .clone()
                .into_sorted_vec()
                .into_iter()
                .map(|InstantAndData(i, id)| (i, id))
                .collect()
        }
    }

    #[cfg(test)]
    impl<Id: Debug + Clone + Hash + Eq> FakeTimerCtx<Id> {
        /// Asserts that `self` contains exactly the timers in `timers`.
        ///
        /// # Panics
        ///
        /// Panics if `timers` contains the same ID more than once or if `self`
        /// does not contain exactly the timers in `timers`.
        ///
        /// [`RangeBounds<FakeInstant>`]: core::ops::RangeBounds
        #[track_caller]
        pub(crate) fn assert_timers_installed<I: IntoIterator<Item = (Id, FakeInstant)>>(
            &self,
            timers: I,
        ) {
            self.assert_timers_installed_range(
                timers.into_iter().map(|(id, instant)| (id, instant..=instant)),
            );
        }

        /// Like [`assert_timers_installed`] but receives a range instants to
        /// match.
        ///
        /// Each timer must be present, and its deadline must fall into the
        /// specified range.
        #[track_caller]
        pub(crate) fn assert_timers_installed_range<
            R: ops::RangeBounds<FakeInstant> + Debug,
            I: IntoIterator<Item = (Id, R)>,
        >(
            &self,
            timers: I,
        ) {
            self.assert_timers_installed_inner(timers, true);
        }

        /// Asserts that `self` contains at least the timers in `timers`.
        ///
        /// Like [`assert_timers_installed`], but only asserts that `timers` is
        /// a subset of the timers installed; other timers may be installed in
        /// addition to those in `timers`.
        #[track_caller]
        pub(crate) fn assert_some_timers_installed<I: IntoIterator<Item = (Id, FakeInstant)>>(
            &self,
            timers: I,
        ) {
            self.assert_some_timers_installed_range(
                timers.into_iter().map(|(id, instant)| (id, instant..=instant)),
            );
        }

        /// Like [`assert_some_timers_installed`] but receives instant ranges
        /// to match like [`assert_timers_installed_range`].
        #[track_caller]
        pub(crate) fn assert_some_timers_installed_range<
            R: ops::RangeBounds<FakeInstant> + Debug,
            I: IntoIterator<Item = (Id, R)>,
        >(
            &self,
            timers: I,
        ) {
            self.assert_timers_installed_inner(timers, false);
        }

        /// Asserts that no timers are installed.
        ///
        /// # Panics
        ///
        /// Panics if any timers are installed.
        #[track_caller]
        pub(crate) fn assert_no_timers_installed(&self) {
            self.assert_timers_installed([]);
        }

        #[track_caller]
        fn assert_timers_installed_inner<
            R: ops::RangeBounds<FakeInstant> + Debug,
            I: IntoIterator<Item = (Id, R)>,
        >(
            &self,
            timers: I,
            exact: bool,
        ) {
            let mut timers = timers.into_iter().fold(HashMap::new(), |mut timers, (id, range)| {
                assert_matches!(timers.insert(id, range), None);
                timers
            });

            enum Error<Id, R: ops::RangeBounds<FakeInstant>> {
                ExpectedButMissing { id: Id, range: R },
                UnexpectedButPresent { id: Id, instant: FakeInstant },
                UnexpectedInstant { id: Id, range: R, instant: FakeInstant },
            }

            let mut errors = Vec::new();

            // Make sure that all installed timers were expected (present in
            // `timers`).
            for InstantAndData(instant, id) in self.timers.iter().cloned() {
                match timers.remove(&id) {
                    None => {
                        if exact {
                            errors.push(Error::UnexpectedButPresent { id, instant })
                        }
                    }
                    Some(range) => {
                        if !range.contains(&instant) {
                            errors.push(Error::UnexpectedInstant { id, range, instant })
                        }
                    }
                }
            }

            // Make sure that all expected timers were already found in
            // `self.timers` (and removed from `timers`).
            errors
                .extend(timers.drain().map(|(id, range)| Error::ExpectedButMissing { id, range }));

            if errors.len() > 0 {
                let mut s = String::from("Unexpected timer contents:");
                for err in errors {
                    s += &match err {
                        Error::ExpectedButMissing { id, range } => {
                            format!("\n\tMissing timer {:?} with deadline {:?}", id, range)
                        }
                        Error::UnexpectedButPresent { id, instant } => {
                            format!("\n\tUnexpected timer {:?} with deadline {:?}", id, instant)
                        }
                        Error::UnexpectedInstant { id, range, instant } => format!(
                            "\n\tTimer {:?} has unexpected deadline {:?} (wanted {:?})",
                            id, instant, range
                        ),
                    };
                }
                panic!("{}", s);
            }
        }
    }

    impl<Id> AsRef<FakeInstantCtx> for FakeTimerCtx<Id> {
        fn as_ref(&self) -> &FakeInstantCtx {
            &self.instant
        }
    }

    impl<Id: PartialEq> FakeTimerCtx<Id> {
        // Just like `TimerContext::cancel_timer`, but takes a reference to `Id`
        // rather than a value. This allows us to implement
        // `schedule_timer_instant`, which needs to retain ownership of the
        // `Id`.
        fn cancel_timer_inner(&mut self, id: &Id) -> Option<FakeInstant> {
            let mut r: Option<FakeInstant> = None;
            // NOTE(brunodalbo): Cancelling timers can be made a faster than
            // this if we keep two data structures and require that `Id: Hash`.
            self.timers = self
                .timers
                .drain()
                .filter(|t| {
                    if &t.1 == id {
                        r = Some(t.0);
                        false
                    } else {
                        true
                    }
                })
                .collect::<Vec<_>>()
                .into();
            r
        }
    }

    // TODO(https://fxbug.dev/42083407): Improve the fake timer implementation
    // to not rely on hashing the dispatch IDs. This implementation gives us a
    // way to soft transition to the new world, but the new API is not asking
    // for DispatchId uniqueness between timers, even though that's how current
    // usage works.
    impl<Id: Debug + Clone + Send + Sync> TimerBindingsTypes for FakeTimerCtx<Id> {
        type Timer = Id;
        type DispatchId = Id;
    }

    impl<Id: PartialEq + Debug + Clone + Send + Sync> TimerContext2 for FakeTimerCtx<Id> {
        fn new_timer(&mut self, id: Self::DispatchId) -> Self::Timer {
            id
        }

        fn schedule_timer_instant2(
            &mut self,
            time: Self::Instant,
            timer: &mut Self::Timer,
        ) -> Option<Self::Instant> {
            self.schedule_timer_instant(time, timer.clone())
        }

        fn cancel_timer2(&mut self, timer: &mut Self::Timer) -> Option<Self::Instant> {
            self.cancel_timer(timer.clone())
        }

        fn scheduled_instant2(&self, timer: &mut Self::Timer) -> Option<Self::Instant> {
            self.scheduled_instant(timer.clone())
        }
    }

    impl<Id: PartialEq> TimerContext<Id> for FakeTimerCtx<Id> {
        fn schedule_timer_instant(&mut self, time: FakeInstant, id: Id) -> Option<FakeInstant> {
            let ret = self.cancel_timer_inner(&id);
            self.timers.push(InstantAndData::new(time, id));
            ret
        }

        fn cancel_timer(&mut self, id: Id) -> Option<FakeInstant> {
            self.cancel_timer_inner(&id)
        }

        fn cancel_timers_with<F: FnMut(&Id) -> bool>(&mut self, mut f: F) {
            self.timers = self.timers.drain().filter(|t| !f(&t.1)).collect::<Vec<_>>().into();
        }

        fn scheduled_instant(&self, id: Id) -> Option<FakeInstant> {
            self.timers.iter().find_map(|x| if x.1 == id { Some(x.0) } else { None })
        }
    }

    /// Adds methods for interacting with [`FakeTimerCtx`] and its wrappers.
    pub trait FakeTimerCtxExt<Id>: Sized {
        /// Triggers the next timer, if any, by using the provided `handler`.
        ///
        /// `trigger_next_timer` triggers the next timer, if any, advances the
        /// internal clock to the timer's scheduled time, and returns its ID.
        fn trigger_next_timer<H: TimerHandler<Self, Id>>(&mut self, handler: &mut H) -> Option<Id>;

        /// Skips the current time forward until `instant`, triggering all
        /// timers until then, inclusive, by calling `f` on them.
        ///
        /// Returns the timers which were triggered.
        ///
        /// # Panics
        ///
        /// Panics if `instant` is in the past.
        fn trigger_timers_until_instant<H: TimerHandler<Self, Id>>(
            &mut self,
            instant: FakeInstant,
            handler: &mut H,
        ) -> Vec<Id>;

        /// Skips the current time forward by `duration`, triggering all timers
        /// until then, inclusive, by passing them to the `handler`.
        ///
        /// Returns the timers which were triggered.
        fn trigger_timers_for<H: TimerHandler<Self, Id>>(
            &mut self,
            duration: Duration,
            handler: &mut H,
        ) -> Vec<Id>;

        /// Triggers timers and expects them to be the given timers.
        ///
        /// The number of timers to be triggered is taken to be the number of
        /// timers produced by `timers`. Timers may be triggered in any order.
        ///
        /// # Panics
        ///
        /// Panics under the following conditions:
        /// - Fewer timers could be triggered than expected
        /// - Timers were triggered that were not expected
        /// - Timers that were expected were not triggered
        #[track_caller]
        fn trigger_timers_and_expect_unordered<
            I: IntoIterator<Item = Id>,
            H: TimerHandler<Self, Id>,
        >(
            &mut self,
            timers: I,
            handler: &mut H,
        ) where
            Id: Debug + Hash + Eq;

        /// Triggers timers until `instant` and expects them to be the given
        /// timers.
        ///
        /// Like `trigger_timers_and_expect_unordered`, except that timers will
        /// only be triggered until `instant` (inclusive).
        fn trigger_timers_until_and_expect_unordered<
            I: IntoIterator<Item = Id>,
            H: TimerHandler<Self, Id>,
        >(
            &mut self,
            instant: FakeInstant,
            timers: I,
            handler: &mut H,
        ) where
            Id: Debug + Hash + Eq;

        /// Triggers timers for `duration` and expects them to be the given
        /// timers.
        ///
        /// Like `trigger_timers_and_expect_unordered`, except that timers will
        /// only be triggered for `duration` (inclusive).
        fn trigger_timers_for_and_expect<I: IntoIterator<Item = Id>, H: TimerHandler<Self, Id>>(
            &mut self,
            duration: Duration,
            timers: I,
            handler: &mut H,
        ) where
            Id: Debug + Hash + Eq;
    }

    // TODO(https://fxbug.dev/42081080): hold lock on `FakeTimerCtx` across entire
    // method to avoid potential race conditions.
    impl<Id: Clone, Ctx: WithFakeTimerContext<Id>> FakeTimerCtxExt<Id> for Ctx {
        /// Triggers the next timer, if any, by calling `f` on it.
        ///
        /// `trigger_next_timer` triggers the next timer, if any, advances the
        /// internal clock to the timer's scheduled time, and returns its ID.
        fn trigger_next_timer<H: TimerHandler<Self, Id>>(&mut self, handler: &mut H) -> Option<Id> {
            self.with_fake_timer_ctx_mut(|timers| {
                timers.timers.pop().map(|InstantAndData(t, id)| {
                    timers.instant.time = t;
                    id
                })
            })
            .map(|id| {
                handler.handle_timer(self, id.clone());
                id
            })
        }

        /// Skips the current time forward until `instant`, triggering all
        /// timers until then, inclusive, by giving them to `handler`.
        ///
        /// Returns the timers which were triggered.
        ///
        /// # Panics
        ///
        /// Panics if `instant` is in the past.
        fn trigger_timers_until_instant<H: TimerHandler<Self, Id>>(
            &mut self,
            instant: FakeInstant,
            handler: &mut H,
        ) -> Vec<Id> {
            assert!(instant >= self.with_fake_timer_ctx(|ctx| ctx.now()));
            let mut timers = Vec::new();

            while self.with_fake_timer_ctx_mut(|ctx| {
                ctx.timers.peek().map(|InstantAndData(i, _id)| i <= &instant).unwrap_or(false)
            }) {
                timers.push(self.trigger_next_timer(handler).unwrap())
            }

            self.with_fake_timer_ctx_mut(|ctx| {
                assert!(ctx.now() <= instant);
                ctx.instant.time = instant;
            });

            timers
        }

        /// Skips the current time forward by `duration`, triggering all timers
        /// until then, inclusive, by calling `f` on them.
        ///
        /// Returns the timers which were triggered.
        fn trigger_timers_for<H: TimerHandler<Self, Id>>(
            &mut self,
            duration: Duration,
            handler: &mut H,
        ) -> Vec<Id> {
            let instant = self.with_fake_timer_ctx(|ctx| ctx.now().saturating_add(duration));
            // We know the call to `self.trigger_timers_until_instant` will not
            // panic because we provide an instant that is greater than or equal
            // to the current time.
            self.trigger_timers_until_instant(instant, handler)
        }

        /// Triggers timers and expects them to be the given timers.
        ///
        /// The number of timers to be triggered is taken to be the number of
        /// timers produced by `timers`. Timers may be triggered in any order.
        ///
        /// # Panics
        ///
        /// Panics under the following conditions:
        /// - Fewer timers could be triggered than expected
        /// - Timers were triggered that were not expected
        /// - Timers that were expected were not triggered
        #[track_caller]
        fn trigger_timers_and_expect_unordered<
            I: IntoIterator<Item = Id>,
            H: TimerHandler<Self, Id>,
        >(
            &mut self,
            timers: I,
            handler: &mut H,
        ) where
            Id: Debug + Hash + Eq,
        {
            let mut timers = RefCountedHashSet::from_iter(timers);

            for _ in 0..timers.len() {
                let id = self.trigger_next_timer(handler).expect("ran out of timers to trigger");
                match timers.remove(id.clone()) {
                    RemoveResult::Removed(()) | RemoveResult::StillPresent => {}
                    RemoveResult::NotPresent => panic!("triggered unexpected timer: {:?}", id),
                }
            }

            if timers.len() > 0 {
                let mut s = String::from("Expected timers did not trigger:");
                for (id, count) in timers.iter_counts() {
                    s += &format!("\n\t{count}x {id:?}");
                }
                panic!("{}", s);
            }
        }

        /// Triggers timers until `instant` and expects them to be the given
        /// timers.
        ///
        /// Like `trigger_timers_and_expect_unordered`, except that timers will
        /// only be triggered until `instant` (inclusive).
        fn trigger_timers_until_and_expect_unordered<
            I: IntoIterator<Item = Id>,
            H: TimerHandler<Self, Id>,
        >(
            &mut self,
            instant: FakeInstant,
            timers: I,
            handler: &mut H,
        ) where
            Id: Debug + Hash + Eq,
        {
            let mut timers = RefCountedHashSet::from_iter(timers);

            let triggered_timers = self.trigger_timers_until_instant(instant, handler);

            for id in triggered_timers {
                match timers.remove(id.clone()) {
                    RemoveResult::Removed(()) | RemoveResult::StillPresent => {}
                    RemoveResult::NotPresent => panic!("triggered unexpected timer: {:?}", id),
                }
            }

            if timers.len() > 0 {
                let mut s = String::from("Expected timers did not trigger:");
                for (id, count) in timers.iter_counts() {
                    s += &format!("\n\t{count}x {id:?}");
                }
                panic!("{}", s);
            }
        }

        /// Triggers timers for `duration` and expects them to be the given
        /// timers.
        ///
        /// Like `trigger_timers_and_expect_unordered`, except that timers will
        /// only be triggered for `duration` (inclusive).
        fn trigger_timers_for_and_expect<I: IntoIterator<Item = Id>, H: TimerHandler<Self, Id>>(
            &mut self,
            duration: Duration,
            timers: I,
            handler: &mut H,
        ) where
            Id: Debug + Hash + Eq,
        {
            let instant = self.with_fake_timer_ctx(|ctx| ctx.now().saturating_add(duration));
            self.trigger_timers_until_and_expect_unordered(instant, timers, handler);
        }
    }

    /// A fake [`FrameContext`].
    pub struct FakeFrameCtx<Meta> {
        frames: Vec<(Meta, Vec<u8>)>,
        should_error_for_frame: Option<Box<dyn Fn(&Meta) -> bool + Send>>,
    }

    #[cfg(test)]
    impl<Meta> FakeFrameCtx<Meta> {
        /// Closure which can decide to cause an error to be thrown when
        /// handling a frame, based on the metadata.
        pub(crate) fn set_should_error_for_frame<F: Fn(&Meta) -> bool + Send + 'static>(
            &mut self,
            f: F,
        ) {
            self.should_error_for_frame = Some(Box::new(f));
        }
    }

    impl<Meta> Default for FakeFrameCtx<Meta> {
        fn default() -> FakeFrameCtx<Meta> {
            FakeFrameCtx { frames: Vec::new(), should_error_for_frame: None }
        }
    }

    impl<Meta> FakeFrameCtx<Meta> {
        /// Take all frames sent so far.
        pub(crate) fn take_frames(&mut self) -> Vec<(Meta, Vec<u8>)> {
            core::mem::take(&mut self.frames)
        }

        /// Get the frames sent so far.
        #[cfg(test)]
        pub(crate) fn frames(&self) -> &[(Meta, Vec<u8>)] {
            self.frames.as_slice()
        }

        pub(crate) fn push(&mut self, meta: Meta, frame: Vec<u8>) {
            self.frames.push((meta, frame))
        }
    }

    impl<C, Meta> SendFrameContext<C, Meta> for FakeFrameCtx<Meta> {
        fn send_frame<S>(
            &mut self,
            _bindings_ctx: &mut C,
            metadata: Meta,
            frame: S,
        ) -> Result<(), S>
        where
            S: Serializer,
            S::Buffer: BufferMut,
        {
            if let Some(should_error_for_frame) = &self.should_error_for_frame {
                if should_error_for_frame(&metadata) {
                    return Err(frame);
                }
            }

            let buffer = frame.serialize_vec_outer().map_err(|(_err, s)| s)?;
            self.push(metadata, buffer.as_ref().to_vec());
            Ok(())
        }
    }

    /// A fake [`EventContext`].
    pub struct FakeEventCtx<E: Debug> {
        events: Vec<E>,
        must_watch_all_events: bool,
    }

    impl<E: Debug> EventContext<E> for FakeEventCtx<E> {
        fn on_event(&mut self, event: E) {
            self.events.push(event)
        }
    }

    impl<E: Debug> Drop for FakeEventCtx<E> {
        fn drop(&mut self) {
            if self.must_watch_all_events {
                assert!(
                    self.events.is_empty(),
                    "dropped context with unacknowledged events: {:?}",
                    self.events
                );
            }
        }
    }

    impl<E: Debug> Default for FakeEventCtx<E> {
        fn default() -> Self {
            Self { events: Default::default(), must_watch_all_events: false }
        }
    }

    impl<E: Debug> FakeEventCtx<E> {
        #[cfg(test)]
        pub(crate) fn take(&mut self) -> Vec<E> {
            // Any client that calls `take()` is opting into watching events
            // and must watch them all.
            self.must_watch_all_events = true;
            core::mem::take(&mut self.events)
        }
    }

    /// A fake [`TracingContext`].
    #[derive(Default)]
    pub struct FakeTracingCtx;

    impl TracingContext for FakeTracingCtx {
        type DurationScope = ();

        fn duration(&self, _: &'static CStr) {}
    }

    /// A tuple of device ID and IP version.
    #[derive(Derivative)]
    #[derivative(Debug(bound = ""))]
    pub struct PureIpDeviceAndIpVersion<BT: DeviceLayerTypes> {
        pub(crate) device: PureIpWeakDeviceId<BT>,
        pub(crate) version: IpVersion,
    }

    /// A test helper used to provide an implementation of a bindings context.
    pub(crate) struct FakeBindingsCtx<TimerId, Event: Debug, State, FrameMeta> {
        pub(crate) rng: FakeCryptoRng<XorShiftRng>,
        pub(crate) timers: FakeTimerCtx<TimerId>,
        pub(crate) events: FakeEventCtx<Event>,
        pub(crate) frames: FakeFrameCtx<FrameMeta>,
        state: State,
    }

    impl<TimerId, Event: Debug, State, FrameMeta> ContextProvider
        for FakeBindingsCtx<TimerId, Event, State, FrameMeta>
    {
        type Context = Self;
        fn context(&mut self) -> &mut Self::Context {
            self
        }
    }

    impl<TimerId, Event: Debug, State: Default, FrameMeta> Default
        for FakeBindingsCtx<TimerId, Event, State, FrameMeta>
    {
        fn default() -> Self {
            Self {
                rng: FakeCryptoRng::new_xorshift(0),
                timers: FakeTimerCtx::default(),
                events: FakeEventCtx::default(),
                frames: FakeFrameCtx::default(),
                state: Default::default(),
            }
        }
    }

    impl<TimerId, Event: Debug, State, FrameMeta> FakeBindingsCtx<TimerId, Event, State, FrameMeta> {
        /// Seed the testing RNG with a specific value.
        #[cfg(test)]
        pub(crate) fn seed_rng(&mut self, seed: u128) {
            self.rng = FakeCryptoRng::new_xorshift(seed);
        }

        /// Move the clock forward by the given duration without firing any
        /// timers.
        ///
        /// If any timers are scheduled to fire in the given duration, future
        /// use of this `FakeCoreCtx` may have surprising or buggy behavior.
        #[cfg(test)]
        pub(crate) fn sleep_skip_timers(&mut self, duration: Duration) {
            self.timers.instant.sleep(duration);
        }

        #[cfg(test)]
        pub(crate) fn timer_ctx(&self) -> &FakeTimerCtx<TimerId> {
            &self.timers
        }

        #[cfg(test)]
        pub(crate) fn timer_ctx_mut(&mut self) -> &mut FakeTimerCtx<TimerId> {
            &mut self.timers
        }

        #[cfg(test)]
        pub(crate) fn take_events(&mut self) -> Vec<Event> {
            self.events.take()
        }

        pub(crate) fn frame_ctx_mut(&mut self) -> &mut FakeFrameCtx<FrameMeta> {
            &mut self.frames
        }

        pub(crate) fn state(&self) -> &State {
            &self.state
        }

        pub(crate) fn state_mut(&mut self) -> &mut State {
            &mut self.state
        }
    }

    impl<TimerId, Event: Debug, State, FrameMeta> FilterBindingsTypes
        for FakeBindingsCtx<TimerId, Event, State, FrameMeta>
    {
        type DeviceClass = ();
    }

    impl<TimerId, Event: Debug, State, FrameMeta> RngContext
        for FakeBindingsCtx<TimerId, Event, State, FrameMeta>
    {
        type Rng<'a> = FakeCryptoRng<XorShiftRng> where Self: 'a;

        fn rng(&mut self) -> Self::Rng<'_> {
            self.rng.clone()
        }
    }

    impl<Id, Event: Debug, State, FrameMeta> AsRef<FakeInstantCtx>
        for FakeBindingsCtx<Id, Event, State, FrameMeta>
    {
        fn as_ref(&self) -> &FakeInstantCtx {
            self.timers.as_ref()
        }
    }

    impl<Id, Event: Debug, State, FrameMeta> AsRef<FakeTimerCtx<Id>>
        for FakeBindingsCtx<Id, Event, State, FrameMeta>
    {
        fn as_ref(&self) -> &FakeTimerCtx<Id> {
            &self.timers
        }
    }

    impl<Id, Event: Debug, State, FrameMeta> AsMut<FakeTimerCtx<Id>>
        for FakeBindingsCtx<Id, Event, State, FrameMeta>
    {
        fn as_mut(&mut self) -> &mut FakeTimerCtx<Id> {
            &mut self.timers
        }
    }

    impl<Id: Debug + PartialEq + Clone + Send + Sync, Event: Debug, State, FrameMeta>
        TimerBindingsTypes for FakeBindingsCtx<Id, Event, State, FrameMeta>
    {
        type Timer = <FakeTimerCtx<Id> as TimerBindingsTypes>::Timer;
        type DispatchId = <FakeTimerCtx<Id> as TimerBindingsTypes>::DispatchId;
    }

    impl<Id: Debug + PartialEq + Clone + Send + Sync, Event: Debug, State, FrameMeta> TimerContext2
        for FakeBindingsCtx<Id, Event, State, FrameMeta>
    {
        fn new_timer(&mut self, id: Self::DispatchId) -> Self::Timer {
            self.timers.new_timer(id)
        }

        fn schedule_timer_instant2(
            &mut self,
            time: Self::Instant,
            timer: &mut Self::Timer,
        ) -> Option<Self::Instant> {
            self.timers.schedule_timer_instant2(time, timer)
        }

        fn cancel_timer2(&mut self, timer: &mut Self::Timer) -> Option<Self::Instant> {
            self.timers.cancel_timer2(timer)
        }

        fn scheduled_instant2(&self, timer: &mut Self::Timer) -> Option<Self::Instant> {
            self.timers.scheduled_instant2(timer)
        }
    }

    impl<Id: Debug + PartialEq, Event: Debug, State, FrameMeta> TimerContext<Id>
        for FakeBindingsCtx<Id, Event, State, FrameMeta>
    {
        fn schedule_timer_instant(&mut self, time: FakeInstant, id: Id) -> Option<FakeInstant> {
            self.timers.schedule_timer_instant(time, id)
        }

        fn cancel_timer(&mut self, id: Id) -> Option<FakeInstant> {
            self.timers.cancel_timer(id)
        }

        fn cancel_timers_with<F: FnMut(&Id) -> bool>(&mut self, f: F) {
            self.timers.cancel_timers_with(f);
        }

        fn scheduled_instant(&self, id: Id) -> Option<FakeInstant> {
            self.timers.scheduled_instant(id)
        }
    }

    impl<Id, Event: Debug, State, FrameMeta> EventContext<Event>
        for FakeBindingsCtx<Id, Event, State, FrameMeta>
    {
        fn on_event(&mut self, event: Event) {
            self.events.on_event(event)
        }
    }

    impl<Id, Event: Debug, State, FrameMeta> TracingContext
        for FakeBindingsCtx<Id, Event, State, FrameMeta>
    {
        type DurationScope = ();

        fn duration(&self, _: &'static CStr) {}
    }

    impl<D: LinkDevice, Id, Event: Debug, State, FrameMeta> LinkResolutionContext<D>
        for FakeBindingsCtx<Id, Event, State, FrameMeta>
    {
        type Notifier = FakeLinkResolutionNotifier<D>;
    }

    impl<Id, Event: Debug, State, FrameMeta> crate::ReferenceNotifiers
        for FakeBindingsCtx<Id, Event, State, FrameMeta>
    {
        type ReferenceReceiver<T: 'static> = Never;

        type ReferenceNotifier<T: Send + 'static> = Never;

        fn new_reference_notifier<T: Send + 'static, D: Debug>(
            debug_references: D,
        ) -> (Self::ReferenceNotifier<T>, Self::ReferenceReceiver<T>) {
            // NB: We don't want deferred destruction in core tests. These are
            // always single-threaded and single-task, and we want to encourage
            // explicit cleanup.
            panic!(
                "FakeBindingsCtx can't create deferred reference notifiers for type {}: \
                debug_references={debug_references:?}",
                core::any::type_name::<T>()
            );
        }
    }

    #[derive(Debug)]
    pub(crate) struct FakeLinkResolutionNotifier<D: LinkDevice>(
        Arc<Mutex<Option<Result<D::Address, crate::error::AddressResolutionFailed>>>>,
    );

    impl<D: LinkDevice> LinkResolutionNotifier<D> for FakeLinkResolutionNotifier<D> {
        type Observer =
            Arc<Mutex<Option<Result<D::Address, crate::error::AddressResolutionFailed>>>>;

        fn new() -> (Self, Self::Observer) {
            let inner = Arc::new(Mutex::new(None));
            (Self(inner.clone()), inner)
        }

        fn notify(self, result: Result<D::Address, crate::error::AddressResolutionFailed>) {
            let Self(inner) = self;
            let mut inner = inner.lock();
            assert_eq!(*inner, None, "resolved link address was set more than once");
            *inner = Some(result);
        }
    }

    pub(crate) trait WithFakeTimerContext<TimerId> {
        fn with_fake_timer_ctx<O, F: FnOnce(&FakeTimerCtx<TimerId>) -> O>(&self, f: F) -> O;

        fn with_fake_timer_ctx_mut<O, F: FnOnce(&mut FakeTimerCtx<TimerId>) -> O>(
            &mut self,
            f: F,
        ) -> O;
    }

    #[cfg(test)]
    pub(crate) trait WithFakeFrameContext<SendMeta> {
        fn with_fake_frame_ctx_mut<O, F: FnOnce(&mut FakeFrameCtx<SendMeta>) -> O>(
            &mut self,
            f: F,
        ) -> O;
    }

    #[cfg(test)]
    impl<CC, TimerId, Event: Debug, State> WithFakeTimerContext<TimerId>
        for FakeCtxWithCoreCtx<CC, TimerId, Event, State>
    {
        fn with_fake_timer_ctx<O, F: FnOnce(&FakeTimerCtx<TimerId>) -> O>(&self, f: F) -> O {
            let Self { core_ctx: _, bindings_ctx } = self;
            f(&bindings_ctx.timers)
        }

        fn with_fake_timer_ctx_mut<O, F: FnOnce(&mut FakeTimerCtx<TimerId>) -> O>(
            &mut self,
            f: F,
        ) -> O {
            let Self { core_ctx: _, bindings_ctx } = self;
            f(&mut bindings_ctx.timers)
        }
    }

    #[cfg(test)]
    impl<TimerId, Event: Debug, State, FrameMeta> WithFakeTimerContext<TimerId>
        for FakeBindingsCtx<TimerId, Event, State, FrameMeta>
    {
        fn with_fake_timer_ctx<O, F: FnOnce(&FakeTimerCtx<TimerId>) -> O>(&self, f: F) -> O {
            f(&self.timers)
        }

        fn with_fake_timer_ctx_mut<O, F: FnOnce(&mut FakeTimerCtx<TimerId>) -> O>(
            &mut self,
            f: F,
        ) -> O {
            f(&mut self.timers)
        }
    }

    #[cfg(test)]
    pub(crate) type FakeCtxWithCoreCtx<CC, TimerId, Event, BindingsCtxState> =
        crate::testutil::ContextPair<CC, FakeBindingsCtx<TimerId, Event, BindingsCtxState, ()>>;

    #[cfg(test)]
    pub(crate) type FakeCtx<S, TimerId, Meta, Event, DeviceId, BindingsCtxState> =
        FakeCtxWithCoreCtx<FakeCoreCtx<S, Meta, DeviceId>, TimerId, Event, BindingsCtxState>;

    #[cfg(test)]
    impl<CC, Id, Event: Debug, BindingsCtxState> AsRef<FakeInstantCtx>
        for FakeCtxWithCoreCtx<CC, Id, Event, BindingsCtxState>
    {
        fn as_ref(&self) -> &FakeInstantCtx {
            self.bindings_ctx.timers.as_ref()
        }
    }

    #[cfg(test)]
    impl<CC, Id, Event: Debug, BindingsCtxState> AsRef<FakeTimerCtx<Id>>
        for FakeCtxWithCoreCtx<CC, Id, Event, BindingsCtxState>
    {
        fn as_ref(&self) -> &FakeTimerCtx<Id> {
            &self.bindings_ctx.timers
        }
    }

    #[cfg(test)]
    impl<CC, Id, Event: Debug, BindingsCtxState> AsMut<FakeTimerCtx<Id>>
        for FakeCtxWithCoreCtx<CC, Id, Event, BindingsCtxState>
    {
        fn as_mut(&mut self) -> &mut FakeTimerCtx<Id> {
            &mut self.bindings_ctx.timers
        }
    }

    #[cfg(test)]
    impl<S, Id, Meta, Event: Debug, DeviceId, BindingsCtxState> AsMut<FakeFrameCtx<Meta>>
        for FakeCtx<S, Id, Meta, Event, DeviceId, BindingsCtxState>
    {
        fn as_mut(&mut self) -> &mut FakeFrameCtx<Meta> {
            &mut self.core_ctx.frames
        }
    }

    #[cfg(test)]
    impl<S, Id, Meta, Event: Debug, DeviceId, BindingsCtxState> WithFakeFrameContext<Meta>
        for FakeCtx<S, Id, Meta, Event, DeviceId, BindingsCtxState>
    {
        fn with_fake_frame_ctx_mut<O, F: FnOnce(&mut FakeFrameCtx<Meta>) -> O>(
            &mut self,
            f: F,
        ) -> O {
            f(&mut self.core_ctx.frames)
        }
    }

    #[cfg(test)]
    #[derive(Default)]
    pub(crate) struct Wrapped<Outer, Inner> {
        pub(crate) inner: Inner,
        pub(crate) outer: Outer,
    }

    #[cfg(test)]
    impl<Outer, Inner> ContextProvider for Wrapped<Outer, Inner> {
        type Context = Self;
        fn context(&mut self) -> &mut Self::Context {
            self
        }
    }

    #[cfg(test)]
    pub(crate) type WrappedFakeCoreCtx<Outer, S, Meta, DeviceId> =
        Wrapped<Outer, FakeCoreCtx<S, Meta, DeviceId>>;

    #[cfg(test)]
    impl<Outer, S, Meta, DeviceId> WrappedFakeCoreCtx<Outer, S, Meta, DeviceId> {
        pub(crate) fn with_inner_and_outer_state(inner: S, outer: Outer) -> Self {
            Self { inner: FakeCoreCtx::with_state(inner), outer }
        }
    }

    #[cfg(test)]
    impl<Outer, T, Inner: AsRef<T>> AsRef<T> for Wrapped<Outer, Inner> {
        fn as_ref(&self) -> &T {
            self.inner.as_ref()
        }
    }

    #[cfg(test)]
    impl<Outer, T, Inner: AsMut<T>> AsMut<T> for Wrapped<Outer, Inner> {
        fn as_mut(&mut self) -> &mut T {
            self.inner.as_mut()
        }
    }

    /// A test helper used to provide an implementation of a core context.
    #[cfg(test)]
    #[derive(Derivative)]
    #[derivative(Default(bound = "S: Default"))]
    pub(crate) struct FakeCoreCtx<S, Meta, DeviceId> {
        pub(crate) state: S,
        pub(crate) frames: FakeFrameCtx<Meta>,
        _devices_marker: PhantomData<DeviceId>,
    }

    #[cfg(test)]
    impl<S, Meta, DeviceId> ContextProvider for FakeCoreCtx<S, Meta, DeviceId> {
        type Context = Self;

        fn context(&mut self) -> &mut Self::Context {
            self
        }
    }

    #[cfg(test)]
    impl<S, Meta, DeviceId> AsRef<FakeCoreCtx<S, Meta, DeviceId>> for FakeCoreCtx<S, Meta, DeviceId> {
        fn as_ref(&self) -> &FakeCoreCtx<S, Meta, DeviceId> {
            self
        }
    }

    #[cfg(test)]
    impl<S, Meta, DeviceId> AsMut<FakeCoreCtx<S, Meta, DeviceId>> for FakeCoreCtx<S, Meta, DeviceId> {
        fn as_mut(&mut self) -> &mut FakeCoreCtx<S, Meta, DeviceId> {
            self
        }
    }

    #[cfg(test)]
    impl<I: packet_formats::ip::IpExt, BC: FilterBindingsTypes, S, Meta, DeviceId>
        FilterHandlerProvider<I, BC> for FakeCoreCtx<S, Meta, DeviceId>
    {
        type Handler<'a> = crate::filter::NoopImpl where Self: 'a;

        fn filter_handler(&mut self) -> Self::Handler<'_> {
            crate::filter::NoopImpl
        }
    }

    #[cfg(test)]
    impl<Outer, I: packet_formats::ip::IpExt, BC: FilterBindingsTypes, S, Meta, DeviceId>
        FilterHandlerProvider<I, BC> for Wrapped<Outer, FakeCoreCtx<S, Meta, DeviceId>>
    {
        type Handler<'a> = crate::filter::NoopImpl where Self: 'a;

        fn filter_handler(&mut self) -> Self::Handler<'_> {
            crate::filter::NoopImpl
        }
    }

    #[cfg(test)]
    impl<BC, S, Meta, DeviceId> CounterContext<BC> for FakeCoreCtx<S, Meta, DeviceId>
    where
        S: CounterContext<BC>,
    {
        fn with_counters<O, F: FnOnce(&BC) -> O>(&self, cb: F) -> O {
            CounterContext::<BC>::with_counters(&self.state, cb)
        }
    }

    #[cfg(test)]
    impl<S, Meta, DeviceId> FakeCoreCtx<S, Meta, DeviceId> {
        /// Constructs a `FakeCoreCtx` with the given state and default
        /// `FakeTimerCtx`, and `FakeFrameCtx`.
        pub(crate) fn with_state(state: S) -> Self {
            FakeCoreCtx { state, frames: FakeFrameCtx::default(), _devices_marker: PhantomData }
        }

        /// Get an immutable reference to the inner state.
        ///
        /// This method is provided instead of an [`AsRef`] impl to avoid
        /// conflicting with user-provided implementations of `AsRef<T> for
        /// FakeCtx<S, Id, Meta, Event>` for other types, `T`. It is named
        /// `get_ref` instead of `as_ref` so that programmer doesn't need to
        /// specify which `as_ref` method is intended.
        pub(crate) fn get_ref(&self) -> &S {
            &self.state
        }

        /// Get a mutable reference to the inner state.
        ///
        /// `get_mut` is like `get_ref`, but it returns a mutable reference.
        pub(crate) fn get_mut(&mut self) -> &mut S {
            &mut self.state
        }

        /// Get the list of frames sent so far.
        pub(crate) fn frames(&self) -> &[(Meta, Vec<u8>)] {
            self.frames.frames()
        }

        /// Take the list of frames sent so far.
        pub(crate) fn take_frames(&mut self) -> Vec<(Meta, Vec<u8>)> {
            self.frames.take_frames()
        }

        /// Consumes the `FakeCoreCtx` and returns the inner state.
        pub(crate) fn into_state(self) -> S {
            self.state
        }
    }

    #[cfg(test)]
    impl<S, Meta, DeviceId> AsMut<FakeFrameCtx<Meta>> for FakeCoreCtx<S, Meta, DeviceId> {
        fn as_mut(&mut self) -> &mut FakeFrameCtx<Meta> {
            &mut self.frames
        }
    }

    #[cfg(test)]
    impl<S, Meta, DeviceId> WithFakeFrameContext<Meta> for FakeCoreCtx<S, Meta, DeviceId> {
        fn with_fake_frame_ctx_mut<O, F: FnOnce(&mut FakeFrameCtx<Meta>) -> O>(
            &mut self,
            f: F,
        ) -> O {
            f(&mut self.frames)
        }
    }

    #[cfg(test)]
    impl<Outer, Inner: WithFakeFrameContext<Meta>, Meta> WithFakeFrameContext<Meta>
        for Wrapped<Outer, Inner>
    {
        fn with_fake_frame_ctx_mut<O, F: FnOnce(&mut FakeFrameCtx<Meta>) -> O>(
            &mut self,
            f: F,
        ) -> O {
            self.inner.with_fake_frame_ctx_mut(f)
        }
    }

    #[cfg(test)]
    impl<S, Id, Meta, Event: Debug, DeviceId, BindingsCtxState, FrameMeta>
        SendFrameContext<FakeBindingsCtx<Id, Event, BindingsCtxState, FrameMeta>, Meta>
        for FakeCoreCtx<S, Meta, DeviceId>
    {
        fn send_frame<SS>(
            &mut self,
            bindings_ctx: &mut FakeBindingsCtx<Id, Event, BindingsCtxState, FrameMeta>,
            metadata: Meta,
            frame: SS,
        ) -> Result<(), SS>
        where
            SS: Serializer,
            SS::Buffer: BufferMut,
        {
            self.frames.send_frame(bindings_ctx, metadata, frame)
        }
    }

    #[cfg(test)]
    #[derive(Debug)]
    pub(crate) struct PendingFrameData<CtxId, Meta> {
        pub(crate) dst_context: CtxId,
        pub(crate) meta: Meta,
        pub(crate) frame: Vec<u8>,
    }

    #[cfg(test)]
    pub(crate) type PendingFrame<CtxId, Meta> = InstantAndData<PendingFrameData<CtxId, Meta>>;

    /// A fake network, composed of many `FakeCoreCtx`s.
    ///
    /// Provides a utility to have many contexts keyed by `CtxId` that can
    /// exchange frames.
    #[cfg(test)]
    pub(crate) struct FakeNetwork<CtxId, Ctx: FakeNetworkContext, Links>
    where
        Links: FakeNetworkLinks<Ctx::SendMeta, Ctx::RecvMeta, CtxId>,
    {
        links: Links,
        current_time: FakeInstant,
        pending_frames: BinaryHeap<PendingFrame<CtxId, Ctx::RecvMeta>>,
        // Declare `contexts` last to ensure that it is dropped last. See
        // https://doc.rust-lang.org/std/ops/trait.Drop.html#drop-order for
        // details.
        contexts: HashMap<CtxId, Ctx>,
    }

    /// A context which can be used with a [`FakeNetwork`].
    #[cfg(test)]
    pub(crate) trait FakeNetworkContext {
        /// The type of timer IDs installed by this context.
        type TimerId;
        /// The type of metadata associated with frames sent by this context.
        type SendMeta;
        /// The type of metadata associated with frames received by this
        /// context.
        type RecvMeta;

        /// Handles a single received frame in this context.
        fn handle_frame(&mut self, recv: Self::RecvMeta, data: Buf<Vec<u8>>);
        /// Handles a single timer id in this context.
        fn handle_timer(&mut self, timer: Self::TimerId);
        /// Processes any context-internal queues, returning `true` if any work
        /// was done.
        ///
        /// This is used to drive queued frames that may be sitting inside the
        /// context and invisible to the [`FakeNetwork`].
        fn process_queues(&mut self) -> bool;
    }

    /// A set of links in a `FakeNetwork`.
    ///
    /// A `FakeNetworkLinks` represents the set of links in a `FakeNetwork`.
    /// It exposes the link information by providing the ability to map from a
    /// frame's sending metadata - including its context, local state, and
    /// `SendMeta` - to the set of appropriate receivers, each represented by
    /// a context ID, receive metadata, and latency.
    #[cfg(test)]
    pub(crate) trait FakeNetworkLinks<SendMeta, RecvMeta, CtxId> {
        fn map_link(&self, ctx: CtxId, meta: SendMeta) -> Vec<(CtxId, RecvMeta, Option<Duration>)>;
    }

    #[cfg(test)]
    impl<
            SendMeta,
            RecvMeta,
            CtxId,
            F: Fn(CtxId, SendMeta) -> Vec<(CtxId, RecvMeta, Option<Duration>)>,
        > FakeNetworkLinks<SendMeta, RecvMeta, CtxId> for F
    {
        fn map_link(&self, ctx: CtxId, meta: SendMeta) -> Vec<(CtxId, RecvMeta, Option<Duration>)> {
            (self)(ctx, meta)
        }
    }

    /// The result of a single step in a `FakeNetwork`
    #[cfg(test)]
    #[derive(Debug)]
    pub(crate) struct StepResult {
        pub(crate) timers_fired: usize,
        pub(crate) frames_sent: usize,
        pub(crate) contexts_with_queued_frames: usize,
    }

    #[cfg(test)]
    impl StepResult {
        fn new(
            timers_fired: usize,
            frames_sent: usize,
            contexts_with_queued_frames: usize,
        ) -> Self {
            Self { timers_fired, frames_sent, contexts_with_queued_frames }
        }

        fn new_idle() -> Self {
            Self::new(0, 0, 0)
        }

        /// Returns `true` if the last step did not perform any operations.
        pub(crate) fn is_idle(&self) -> bool {
            return self.timers_fired == 0
                && self.frames_sent == 0
                && self.contexts_with_queued_frames == 0;
        }
    }

    #[cfg(test)]
    impl<CtxId, Ctx, Links> FakeNetwork<CtxId, Ctx, Links>
    where
        CtxId: Eq + Hash + Copy + Debug,
        Ctx: FakeNetworkContext,
        Links: FakeNetworkLinks<Ctx::SendMeta, Ctx::RecvMeta, CtxId>,
    {
        /// Retrieves a context named `context`.
        pub(crate) fn context<K: Into<CtxId>>(&mut self, context: K) -> &mut Ctx {
            self.contexts.get_mut(&context.into()).unwrap()
        }

        pub(crate) fn with_context<K: Into<CtxId>, O, F: FnOnce(&mut Ctx) -> O>(
            &mut self,
            context: K,
            f: F,
        ) -> O {
            f(self.context(context))
        }
    }

    #[cfg(test)]
    impl<CtxId, Ctx, Links> FakeNetwork<CtxId, Ctx, Links>
    where
        CtxId: Eq + Hash + Copy + Debug,
        Ctx: FakeNetworkContext
            + WithFakeTimerContext<Ctx::TimerId>
            + WithFakeFrameContext<Ctx::SendMeta>,
        Ctx::TimerId: Clone,
        Links: FakeNetworkLinks<Ctx::SendMeta, Ctx::RecvMeta, CtxId>,
    {
        /// Creates a new `FakeNetwork`.
        ///
        /// Creates a new `FakeNetwork` with the collection of `FakeCoreCtx`s in
        /// `contexts`. `Ctx`s are named by type parameter `CtxId`.
        ///
        /// # Panics
        ///
        /// Calls to `new` will panic if given a `FakeCoreCtx` with timer events.
        /// `FakeCoreCtx`s given to `FakeNetwork` **must not** have any timer
        /// events already attached to them, because `FakeNetwork` maintains
        /// all the internal timers in dispatchers in sync to enable synchronous
        /// simulation steps.
        pub(crate) fn new<I: IntoIterator<Item = (CtxId, Ctx)>>(contexts: I, links: Links) -> Self {
            let mut contexts = contexts.into_iter().collect::<HashMap<_, _>>();
            // Take the current time to be the latest of the times of any of the
            // contexts. This ensures that no context has state which is based
            // on having observed a time in the future, which could cause bugs.
            // For any contexts which have a time further in the past, it will
            // appear as though time has jumped forwards, but that's fine. The
            // only way that this could be a problem would be if a timer were
            // installed which should have fired in the interim (code might
            // become buggy in this case). However, we assert below that no
            // timers are installed.
            let latest_time = contexts
                .iter()
                .map(|(_, ctx)| ctx.with_fake_timer_ctx(|ctx| ctx.instant.time))
                .max()
                // If `max` returns `None`, it means that we were called with no
                // contexts. That's kind of silly, but whatever - arbitrarily
                // choose the current time as the epoch.
                .unwrap_or(FakeInstant::default());

            assert!(
                !contexts
                    .iter()
                    .any(|(_, ctx)| { !ctx.with_fake_timer_ctx(|ctx| ctx.timers.is_empty()) }),
                "can't start network with contexts that already have timers set"
            );

            // Synchronize all contexts' current time to the latest time of any
            // of the contexts. See comment above for more details.
            for (_, ctx) in contexts.iter_mut() {
                ctx.with_fake_timer_ctx_mut(|ctx| ctx.instant.time = latest_time);
            }

            Self { contexts, current_time: latest_time, pending_frames: BinaryHeap::new(), links }
        }

        /// Iterates over pending frames in an arbitrary order.
        pub(crate) fn iter_pending_frames(
            &self,
        ) -> impl Iterator<Item = &PendingFrame<CtxId, Ctx::RecvMeta>> {
            self.pending_frames.iter()
        }

        /// Drops all pending frames; they will not be delivered.
        pub(crate) fn drop_pending_frames(&mut self) {
            self.pending_frames.clear();
        }

        /// Performs a single step in network simulation.
        ///
        /// `step` performs a single logical step in the collection of `Ctx`s
        /// held by this `FakeNetwork`. A single step consists of the following
        /// operations:
        ///
        /// - All pending frames, kept in each `FakeCoreCtx`, are mapped to their
        ///   destination context/device pairs and moved to an internal
        ///   collection of pending frames.
        /// - The collection of pending timers and scheduled frames is inspected
        ///   and a simulation time step is retrieved, which will cause a next
        ///   event to trigger. The simulation time is updated to the new time.
        /// - All scheduled frames whose deadline is less than or equal to the
        ///   new simulation time are sent to their destinations, handled using
        ///   `handle_frame`.
        /// - All timer events whose deadline is less than or equal to the new
        ///   simulation time are fired, handled using `handle_timer`.
        ///
        /// If any new events are created during the operation of frames or
        /// timers, they **will not** be taken into account in the current
        /// `step`. That is, `step` collects all the pending events before
        /// dispatching them, ensuring that an infinite loop can't be created as
        /// a side effect of calling `step`.
        ///
        /// The return value of `step` indicates which of the operations were
        /// performed.
        ///
        /// # Panics
        ///
        /// If `FakeNetwork` was set up with a bad `links`, calls to `step` may
        /// panic when trying to route frames to their context/device
        /// destinations.
        pub(crate) fn step(&mut self) -> StepResult
        where
            Ctx::TimerId: core::fmt::Debug,
        {
            self.step_with(|_, meta, buf| Some((meta, buf)))
        }

        /// Like [`FakeNetwork::step`], but receives a function
        /// `filter_map_frame` that can modify the an inbound frame before
        /// delivery or drop it altogether by returning `None`.
        pub(crate) fn step_with<
            F: FnMut(&mut Ctx, Ctx::RecvMeta, Buf<Vec<u8>>) -> Option<(Ctx::RecvMeta, Buf<Vec<u8>>)>,
        >(
            &mut self,
            mut filter_map_frame: F,
        ) -> StepResult
        where
            Ctx::TimerId: core::fmt::Debug,
        {
            let mut ret = StepResult::new_idle();
            // Drive all queues before checking for the network and time
            // simulation.
            for (_, ctx) in self.contexts.iter_mut() {
                if ctx.process_queues() {
                    ret.contexts_with_queued_frames += 1;
                }
            }

            self.collect_frames();

            let next_step = if let Some(t) = self.next_step() {
                t
            } else {
                return ret;
            };

            // This assertion holds the contract that `next_step` does not
            // return a time in the past.
            assert!(next_step >= self.current_time);

            // Move time forward:
            self.current_time = next_step;
            for (_, ctx) in self.contexts.iter_mut() {
                ctx.with_fake_timer_ctx_mut(|ctx| ctx.instant.time = next_step);
            }

            // Dispatch all pending frames:
            while let Some(InstantAndData(t, _)) = self.pending_frames.peek() {
                // TODO(https://github.com/rust-lang/rust/issues/53667): Remove
                // this break once let_chains is stable.
                if *t > self.current_time {
                    break;
                }
                // We can unwrap because we just peeked.
                let PendingFrameData { dst_context, meta, frame } =
                    self.pending_frames.pop().unwrap().1;
                let dst_context = self.context(dst_context);
                if let Some((meta, frame)) =
                    filter_map_frame(dst_context, meta, Buf::new(frame, ..))
                {
                    dst_context.handle_frame(meta, frame)
                }
                ret.frames_sent += 1;
            }

            // Dispatch all pending timers.
            for (_, ctx) in self.contexts.iter_mut() {
                // We have to collect the timers before dispatching them, to
                // avoid an infinite loop in case handle_timer schedules another
                // timer for the same or older FakeInstant.
                let mut timers = Vec::<Ctx::TimerId>::new();
                ctx.with_fake_timer_ctx_mut(|ctx| {
                    while let Some(InstantAndData(t, id)) = ctx.timers.peek() {
                        // TODO(https://github.com/rust-lang/rust/issues/53667):
                        // Remove this break once let_chains is stable.
                        if *t > ctx.now() {
                            break;
                        }
                        timers.push(id.clone());
                        assert_ne!(ctx.timers.pop(), None);
                    }
                });

                for t in timers {
                    ctx.handle_timer(t);
                    ret.timers_fired += 1;
                }
            }
            ret
        }

        /// Runs the network until it is starved of events.
        ///
        /// # Panics
        ///
        /// Panics if 1,000,000 steps are performed without becoming idle.
        /// Also panics under the same conditions as [`step`].
        pub(crate) fn run_until_idle(&mut self)
        where
            Ctx::TimerId: core::fmt::Debug,
        {
            self.run_until_idle_with(|_, meta, frame| Some((meta, frame)))
        }

        /// Like [`FakeNetwork::run_until_idle`] but receives a function
        /// `filter_map_frame` that can modify the an inbound frame before
        /// delivery or drop it altogether by returning `None`.
        pub(crate) fn run_until_idle_with<
            F: FnMut(&mut Ctx, Ctx::RecvMeta, Buf<Vec<u8>>) -> Option<(Ctx::RecvMeta, Buf<Vec<u8>>)>,
        >(
            &mut self,
            mut filter_map_frame: F,
        ) where
            Ctx::TimerId: core::fmt::Debug,
        {
            for _ in 0..1_000_000 {
                if self.step_with(&mut filter_map_frame).is_idle() {
                    return;
                }
            }
            panic!("FakeNetwork seems to have gotten stuck in a loop.");
        }

        /// Collects all queued frames.
        ///
        /// Collects all pending frames and schedules them for delivery to the
        /// destination context/device based on the result of `links`. The
        /// collected frames are queued for dispatching in the `FakeNetwork`,
        /// ordered by their scheduled delivery time given by the latency result
        /// provided by `links`.
        pub(crate) fn collect_frames(&mut self) {
            let all_frames: Vec<(CtxId, Vec<(Ctx::SendMeta, Vec<u8>)>)> = self
                .contexts
                .iter_mut()
                .filter_map(|(n, ctx)| {
                    ctx.with_fake_frame_ctx_mut(|ctx| {
                        if ctx.frames.is_empty() {
                            None
                        } else {
                            Some((n.clone(), ctx.frames.drain(..).collect()))
                        }
                    })
                })
                .collect();

            for (src_context, frames) in all_frames.into_iter() {
                for (send_meta, frame) in frames.into_iter() {
                    for (dst_context, recv_meta, latency) in
                        self.links.map_link(src_context, send_meta)
                    {
                        self.pending_frames.push(PendingFrame::new(
                            self.current_time + latency.unwrap_or(Duration::from_millis(0)),
                            PendingFrameData { frame: frame.clone(), dst_context, meta: recv_meta },
                        ));
                    }
                }
            }
        }

        /// Calculates the next `FakeInstant` when events are available.
        ///
        /// Returns the smallest `FakeInstant` greater than or equal to the
        /// current time for which an event is available. If no events are
        /// available, returns `None`.
        pub(crate) fn next_step(&self) -> Option<FakeInstant> {
            // Get earliest timer in all contexts.
            let next_timer = self
                .contexts
                .iter()
                .filter_map(|(_, ctx)| {
                    ctx.with_fake_timer_ctx(|ctx| match ctx.timers.peek() {
                        Some(tmr) => Some(tmr.0),
                        None => None,
                    })
                })
                .min();
            // Get the instant for the next packet.
            let next_packet_due = self.pending_frames.peek().map(|t| t.0);

            // Return the earliest of them both, and protect against returning a
            // time in the past.
            match next_timer {
                Some(t) if next_packet_due.is_some() => Some(t).min(next_packet_due),
                Some(t) => Some(t),
                None => next_packet_due,
            }
            .map(|t| t.max(self.current_time))
        }
    }

    #[cfg(test)]
    impl<CtxId, Links, CC, BC> FakeNetwork<CtxId, crate::testutil::ContextPair<CC, BC>, Links>
    where
        crate::testutil::ContextPair<CC, BC>: FakeNetworkContext,
        CtxId: Eq + Hash + Copy + Debug,
        Links: FakeNetworkLinks<
            <crate::testutil::ContextPair<CC, BC> as FakeNetworkContext>::SendMeta,
            <crate::testutil::ContextPair<CC, BC> as FakeNetworkContext>::RecvMeta,
            CtxId,
        >,
    {
        /// Retrieves a `FakeCoreCtx` named `context`.
        pub(crate) fn core_ctx<K: Into<CtxId>>(&mut self, context: K) -> &mut CC {
            let crate::testutil::ContextPair { core_ctx, bindings_ctx: _ } = self.context(context);
            core_ctx
        }

        /// Retrieves a `FakeBindingsCtx` named `context`.
        pub(crate) fn bindings_ctx<K: Into<CtxId>>(&mut self, context: K) -> &mut BC {
            let crate::testutil::ContextPair { core_ctx: _, bindings_ctx } = self.context(context);
            bindings_ctx
        }
    }

    /// Creates a new [`FakeNetwork`] of [`Ctx`]s in a simple two-host
    /// configuration.
    ///
    /// Two hosts are created with the given names. Packets emitted by one
    /// arrive at the other and vice-versa.
    #[cfg(test)]
    pub(crate) fn new_simple_fake_network<CtxId: Copy + Debug + Hash + Eq>(
        a_id: CtxId,
        a: crate::testutil::FakeCtx,
        a_device_id: EthernetWeakDeviceId<crate::testutil::FakeBindingsCtx>,
        b_id: CtxId,
        b: crate::testutil::FakeCtx,
        b_device_id: EthernetWeakDeviceId<crate::testutil::FakeBindingsCtx>,
    ) -> FakeNetwork<
        CtxId,
        crate::testutil::FakeCtx,
        impl FakeNetworkLinks<
            DispatchedFrame,
            EthernetDeviceId<crate::testutil::FakeBindingsCtx>,
            CtxId,
        >,
    > {
        let contexts = vec![(a_id, a), (b_id, b)].into_iter();
        FakeNetwork::new(contexts, move |net, _frame: DispatchedFrame| {
            if net == a_id {
                b_device_id
                    .upgrade()
                    .map(|device_id| (b_id, device_id, None))
                    .into_iter()
                    .collect::<Vec<_>>()
            } else {
                a_device_id
                    .upgrade()
                    .map(|device_id| (a_id, device_id, None))
                    .into_iter()
                    .collect::<Vec<_>>()
            }
        })
    }

    #[cfg(test)]
    mod tests {
        use crate::device::testutil::FakeDeviceId;

        use super::*;

        const ONE_SEC: Duration = Duration::from_secs(1);
        const ONE_SEC_INSTANT: FakeInstant = FakeInstant { offset: ONE_SEC };

        #[test]
        fn test_instant_and_data() {
            // Verify implementation of InstantAndData to be used as a complex
            // type in a BinaryHeap.
            let mut heap = BinaryHeap::<InstantAndData<usize>>::new();
            let now = FakeInstant::default();

            fn new_data(time: FakeInstant, id: usize) -> InstantAndData<usize> {
                InstantAndData::new(time, id)
            }

            heap.push(new_data(now + Duration::from_secs(1), 1));
            heap.push(new_data(now + Duration::from_secs(2), 2));

            // Earlier timer is popped first.
            assert_eq!(heap.pop().unwrap().1, 1);
            assert_eq!(heap.pop().unwrap().1, 2);
            assert_eq!(heap.pop(), None);

            heap.push(new_data(now + Duration::from_secs(1), 1));
            heap.push(new_data(now + Duration::from_secs(1), 1));

            // Can pop twice with identical data.
            assert_eq!(heap.pop().unwrap().1, 1);
            assert_eq!(heap.pop().unwrap().1, 1);
            assert_eq!(heap.pop(), None);
        }

        #[test]
        fn test_fake_timer_context() {
            // An implementation of `TimerContext` that uses `usize` timer IDs
            // and stores every timer in a `Vec`.
            impl<M, E: Debug, D, S, F> TimerHandler<FakeBindingsCtx<usize, E, S, F>, usize>
                for FakeCoreCtx<Vec<(usize, FakeInstant)>, M, D>
            {
                fn handle_timer(
                    &mut self,
                    bindings_ctx: &mut FakeBindingsCtx<usize, E, S, F>,
                    id: usize,
                ) {
                    let now = bindings_ctx.now();
                    self.get_mut().push((id, now));
                }
            }

            let new_ctx =
                || FakeCtx::<Vec<(usize, FakeInstant)>, usize, (), (), FakeDeviceId, ()>::default();

            let FakeCtx { mut core_ctx, mut bindings_ctx } = new_ctx();

            // When no timers are installed, `trigger_next_timer` should return
            // `false`.
            assert_eq!(bindings_ctx.trigger_next_timer(&mut core_ctx), None);
            assert_eq!(core_ctx.get_ref().as_slice(), []);

            // When one timer is installed, it should be triggered.
            let FakeCtx { mut core_ctx, mut bindings_ctx } = new_ctx();

            // No timer with id `0` exists yet.
            assert_eq!(bindings_ctx.scheduled_instant(0), None);

            assert_eq!(bindings_ctx.schedule_timer(ONE_SEC, 0), None);

            // Timer with id `0` scheduled to execute at `ONE_SEC_INSTANT`.
            assert_eq!(bindings_ctx.scheduled_instant(0).unwrap(), ONE_SEC_INSTANT);

            assert_eq!(bindings_ctx.trigger_next_timer(&mut core_ctx), Some(0));
            assert_eq!(core_ctx.get_ref().as_slice(), [(0, ONE_SEC_INSTANT)]);

            // After the timer fires, it should not still be scheduled at some
            // instant.
            assert_eq!(bindings_ctx.scheduled_instant(0), None);

            // The time should have been advanced.
            assert_eq!(bindings_ctx.now(), ONE_SEC_INSTANT);

            // Once it's been triggered, it should be canceled and not
            // triggerable again.
            let FakeCtx { mut core_ctx, mut bindings_ctx } = new_ctx();
            assert_eq!(bindings_ctx.trigger_next_timer(&mut core_ctx), None);
            assert_eq!(core_ctx.get_ref().as_slice(), []);

            // If we schedule a timer but then cancel it, it shouldn't fire.
            let FakeCtx { mut core_ctx, mut bindings_ctx } = new_ctx();

            assert_eq!(bindings_ctx.schedule_timer(ONE_SEC, 0), None);
            assert_eq!(bindings_ctx.cancel_timer(0), Some(ONE_SEC_INSTANT));
            assert_eq!(bindings_ctx.trigger_next_timer(&mut core_ctx), None);
            assert_eq!(core_ctx.get_ref().as_slice(), []);

            // If we schedule a timer but then schedule the same ID again, the
            // second timer should overwrite the first one.
            let FakeCtx { core_ctx: _, mut bindings_ctx } = new_ctx();
            assert_eq!(bindings_ctx.schedule_timer(Duration::from_secs(0), 0), None);
            assert_eq!(
                bindings_ctx.schedule_timer(ONE_SEC, 0),
                Some(Duration::from_secs(0).into())
            );
            assert_eq!(bindings_ctx.cancel_timer(0), Some(ONE_SEC_INSTANT));

            // If we schedule three timers and then run `trigger_timers_until`
            // with the appropriate value, only two of them should fire.
            let FakeCtx { mut core_ctx, mut bindings_ctx } = new_ctx();
            assert_eq!(bindings_ctx.schedule_timer(Duration::from_secs(0), 0), None,);
            assert_eq!(bindings_ctx.schedule_timer(Duration::from_secs(1), 1), None,);
            assert_eq!(bindings_ctx.schedule_timer(Duration::from_secs(2), 2), None,);
            assert_eq!(
                bindings_ctx.trigger_timers_until_instant(ONE_SEC_INSTANT, &mut core_ctx),
                vec![0, 1],
            );

            // The first two timers should have fired.
            assert_eq!(
                core_ctx.get_ref().as_slice(),
                [(0, FakeInstant::from(Duration::from_secs(0))), (1, ONE_SEC_INSTANT)]
            );

            // They should be canceled now.
            assert_eq!(bindings_ctx.cancel_timer(0), None);
            assert_eq!(bindings_ctx.cancel_timer(1), None);

            // The clock should have been updated.
            assert_eq!(bindings_ctx.now(), ONE_SEC_INSTANT);

            // The last timer should not have fired.
            assert_eq!(
                bindings_ctx.cancel_timer(2),
                Some(FakeInstant::from(Duration::from_secs(2)))
            );
        }

        #[test]
        fn test_trigger_timers_until_and_expect_unordered() {
            // If the requested instant does not coincide with a timer trigger
            // point, the time should still be advanced.
            let FakeCtx { mut core_ctx, mut bindings_ctx } =
                FakeCtx::<Vec<(usize, FakeInstant)>, usize, (), (), FakeDeviceId, ()>::default();
            assert_eq!(bindings_ctx.schedule_timer(Duration::from_secs(0), 0), None);
            assert_eq!(bindings_ctx.schedule_timer(Duration::from_secs(2), 1), None);
            bindings_ctx.trigger_timers_until_and_expect_unordered(
                ONE_SEC_INSTANT,
                vec![0],
                &mut core_ctx,
            );
            assert_eq!(bindings_ctx.now(), ONE_SEC_INSTANT);
        }
    }
}
