// SPDX-License-Identifier: GPL-2.0

// Copyright (C) 2024 Google LLC.

//! A linked list implementation.

use crate::sync::ArcBorrow;
use crate::types::Opaque;
use core::iter::{DoubleEndedIterator, FusedIterator};
use core::marker::PhantomData;
use core::ptr;
use pin_init::PinInit;

mod impl_list_item_mod;
pub use self::impl_list_item_mod::{
    impl_has_list_links, impl_has_list_links_self_ptr, impl_list_item, HasListLinks, HasSelfPtr,
};

mod arc;
pub use self::arc::{impl_list_arc_safe, AtomicTracker, ListArc, ListArcSafe, TryNewListArc};

mod arc_field;
pub use self::arc_field::{define_list_arc_field_getter, ListArcField};

/// A linked list.
///
/// All elements in this linked list will be [`ListArc`] references to the value. Since a value can
/// only have one `ListArc` (for each pair of prev/next pointers), this ensures that the same
/// prev/next pointers are not used for several linked lists.
///
/// # Invariants
///
/// * If the list is empty, then `first` is null. Otherwise, `first` points at the `ListLinks`
///   field of the first element in the list.
/// * All prev/next pointers in `ListLinks` fields of items in the list are valid and form a cycle.
/// * For every item in the list, the list owns the associated [`ListArc`] reference and has
///   exclusive access to the `ListLinks` field.
///
/// # Examples
///
/// Use [`ListLinks`] as the type of the intrusive field.
///
/// ```
/// use kernel::list::*;
///
/// #[pin_data]
/// struct BasicItem {
///     value: i32,
///     #[pin]
///     links: ListLinks,
/// }
///
/// impl BasicItem {
///     fn new(value: i32) -> Result<ListArc<Self>> {
///         ListArc::pin_init(try_pin_init!(Self {
///             value,
///             links <- ListLinks::new(),
///         }), GFP_KERNEL)
///     }
/// }
///
/// impl_list_arc_safe! {
///     impl ListArcSafe<0> for BasicItem { untracked; }
/// }
/// impl_list_item! {
///     impl ListItem<0> for BasicItem { using ListLinks { self.links }; }
/// }
///
/// // Create a new empty list.
/// let mut list = List::new();
/// {
///     assert!(list.is_empty());
/// }
///
/// // Insert 3 elements using `push_back()`.
/// list.push_back(BasicItem::new(15)?);
/// list.push_back(BasicItem::new(10)?);
/// list.push_back(BasicItem::new(30)?);
///
/// // Iterate over the list to verify the nodes were inserted correctly.
/// // [15, 10, 30]
/// {
///     let mut iter = list.iter();
///     assert_eq!(iter.next().ok_or(EINVAL)?.value, 15);
///     assert_eq!(iter.next().ok_or(EINVAL)?.value, 10);
///     assert_eq!(iter.next().ok_or(EINVAL)?.value, 30);
///     assert!(iter.next().is_none());
///
///     // Verify the length of the list.
///     assert_eq!(list.iter().count(), 3);
/// }
///
/// // Pop the items from the list using `pop_back()` and verify the content.
/// {
///     assert_eq!(list.pop_back().ok_or(EINVAL)?.value, 30);
///     assert_eq!(list.pop_back().ok_or(EINVAL)?.value, 10);
///     assert_eq!(list.pop_back().ok_or(EINVAL)?.value, 15);
/// }
///
/// // Insert 3 elements using `push_front()`.
/// list.push_front(BasicItem::new(15)?);
/// list.push_front(BasicItem::new(10)?);
/// list.push_front(BasicItem::new(30)?);
///
/// // Iterate over the list to verify the nodes were inserted correctly.
/// // [30, 10, 15]
/// {
///     let mut iter = list.iter();
///     assert_eq!(iter.next().ok_or(EINVAL)?.value, 30);
///     assert_eq!(iter.next().ok_or(EINVAL)?.value, 10);
///     assert_eq!(iter.next().ok_or(EINVAL)?.value, 15);
///     assert!(iter.next().is_none());
///
///     // Verify the length of the list.
///     assert_eq!(list.iter().count(), 3);
/// }
///
/// // Pop the items from the list using `pop_front()` and verify the content.
/// {
///     assert_eq!(list.pop_front().ok_or(EINVAL)?.value, 30);
///     assert_eq!(list.pop_front().ok_or(EINVAL)?.value, 10);
/// }
///
/// // Push `list2` to `list` through `push_all_back()`.
/// // list: [15]
/// // list2: [25, 35]
/// {
///     let mut list2 = List::new();
///     list2.push_back(BasicItem::new(25)?);
///     list2.push_back(BasicItem::new(35)?);
///
///     list.push_all_back(&mut list2);
///
///     // list: [15, 25, 35]
///     // list2: []
///     let mut iter = list.iter();
///     assert_eq!(iter.next().ok_or(EINVAL)?.value, 15);
///     assert_eq!(iter.next().ok_or(EINVAL)?.value, 25);
///     assert_eq!(iter.next().ok_or(EINVAL)?.value, 35);
///     assert!(iter.next().is_none());
///     assert!(list2.is_empty());
/// }
/// # Result::<(), Error>::Ok(())
/// ```
///
/// Use [`ListLinksSelfPtr`] as the type of the intrusive field. This allows a list of trait object
/// type.
///
/// ```
/// use kernel::list::*;
///
/// trait Foo {
///     fn foo(&self) -> (&'static str, i32);
/// }
///
/// #[pin_data]
/// struct DTWrap<T: ?Sized> {
///     #[pin]
///     links: ListLinksSelfPtr<DTWrap<dyn Foo>>,
///     value: T,
/// }
///
/// impl<T> DTWrap<T> {
///     fn new(value: T) -> Result<ListArc<Self>> {
///         ListArc::pin_init(try_pin_init!(Self {
///             value,
///             links <- ListLinksSelfPtr::new(),
///         }), GFP_KERNEL)
///     }
/// }
///
/// impl_list_arc_safe! {
///     impl{T: ?Sized} ListArcSafe<0> for DTWrap<T> { untracked; }
/// }
/// impl_list_item! {
///     impl ListItem<0> for DTWrap<dyn Foo> { using ListLinksSelfPtr { self.links }; }
/// }
///
/// // Create a new empty list.
/// let mut list = List::<DTWrap<dyn Foo>>::new();
/// {
///     assert!(list.is_empty());
/// }
///
/// struct A(i32);
/// // `A` returns the inner value for `foo`.
/// impl Foo for A { fn foo(&self) -> (&'static str, i32) { ("a", self.0) } }
///
/// struct B;
/// // `B` always returns 42.
/// impl Foo for B { fn foo(&self) -> (&'static str, i32) { ("b", 42) } }
///
/// // Insert 3 element using `push_back()`.
/// list.push_back(DTWrap::new(A(15))?);
/// list.push_back(DTWrap::new(A(32))?);
/// list.push_back(DTWrap::new(B)?);
///
/// // Iterate over the list to verify the nodes were inserted correctly.
/// // [A(15), A(32), B]
/// {
///     let mut iter = list.iter();
///     assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("a", 15));
///     assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("a", 32));
///     assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("b", 42));
///     assert!(iter.next().is_none());
///
///     // Verify the length of the list.
///     assert_eq!(list.iter().count(), 3);
/// }
///
/// // Pop the items from the list using `pop_back()` and verify the content.
/// {
///     assert_eq!(list.pop_back().ok_or(EINVAL)?.value.foo(), ("b", 42));
///     assert_eq!(list.pop_back().ok_or(EINVAL)?.value.foo(), ("a", 32));
///     assert_eq!(list.pop_back().ok_or(EINVAL)?.value.foo(), ("a", 15));
/// }
///
/// // Insert 3 elements using `push_front()`.
/// list.push_front(DTWrap::new(A(15))?);
/// list.push_front(DTWrap::new(A(32))?);
/// list.push_front(DTWrap::new(B)?);
///
/// // Iterate over the list to verify the nodes were inserted correctly.
/// // [B, A(32), A(15)]
/// {
///     let mut iter = list.iter();
///     assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("b", 42));
///     assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("a", 32));
///     assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("a", 15));
///     assert!(iter.next().is_none());
///
///     // Verify the length of the list.
///     assert_eq!(list.iter().count(), 3);
/// }
///
/// // Pop the items from the list using `pop_front()` and verify the content.
/// {
///     assert_eq!(list.pop_back().ok_or(EINVAL)?.value.foo(), ("a", 15));
///     assert_eq!(list.pop_back().ok_or(EINVAL)?.value.foo(), ("a", 32));
/// }
///
/// // Push `list2` to `list` through `push_all_back()`.
/// // list: [B]
/// // list2: [B, A(25)]
/// {
///     let mut list2 = List::<DTWrap<dyn Foo>>::new();
///     list2.push_back(DTWrap::new(B)?);
///     list2.push_back(DTWrap::new(A(25))?);
///
///     list.push_all_back(&mut list2);
///
///     // list: [B, B, A(25)]
///     // list2: []
///     let mut iter = list.iter();
///     assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("b", 42));
///     assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("b", 42));
///     assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("a", 25));
///     assert!(iter.next().is_none());
///     assert!(list2.is_empty());
/// }
/// # Result::<(), Error>::Ok(())
/// ```
pub struct List<T: ?Sized + ListItem<ID>, const ID: u64 = 0> {
    first: *mut ListLinksFields,
    _ty: PhantomData<ListArc<T, ID>>,
}

// SAFETY: This is a container of `ListArc<T, ID>`, and access to the container allows the same
// type of access to the `ListArc<T, ID>` elements.
unsafe impl<T, const ID: u64> Send for List<T, ID>
where
    ListArc<T, ID>: Send,
    T: ?Sized + ListItem<ID>,
{
}
// SAFETY: This is a container of `ListArc<T, ID>`, and access to the container allows the same
// type of access to the `ListArc<T, ID>` elements.
unsafe impl<T, const ID: u64> Sync for List<T, ID>
where
    ListArc<T, ID>: Sync,
    T: ?Sized + ListItem<ID>,
{
}

/// Implemented by types where a [`ListArc<Self>`] can be inserted into a [`List`].
///
/// # Safety
///
/// Implementers must ensure that they provide the guarantees documented on methods provided by
/// this trait.
///
/// [`ListArc<Self>`]: ListArc
pub unsafe trait ListItem<const ID: u64 = 0>: ListArcSafe<ID> {
    /// Views the [`ListLinks`] for this value.
    ///
    /// # Guarantees
    ///
    /// If there is a previous call to `prepare_to_insert` and there is no call to `post_remove`
    /// since the most recent such call, then this returns the same pointer as the one returned by
    /// the most recent call to `prepare_to_insert`.
    ///
    /// Otherwise, the returned pointer points at a read-only [`ListLinks`] with two null pointers.
    ///
    /// # Safety
    ///
    /// The provided pointer must point at a valid value. (It need not be in an `Arc`.)
    unsafe fn view_links(me: *const Self) -> *mut ListLinks<ID>;

    /// View the full value given its [`ListLinks`] field.
    ///
    /// Can only be used when the value is in a list.
    ///
    /// # Guarantees
    ///
    /// * Returns the same pointer as the one passed to the most recent call to `prepare_to_insert`.
    /// * The returned pointer is valid until the next call to `post_remove`.
    ///
    /// # Safety
    ///
    /// * The provided pointer must originate from the most recent call to `prepare_to_insert`, or
    ///   from a call to `view_links` that happened after the most recent call to
    ///   `prepare_to_insert`.
    /// * Since the most recent call to `prepare_to_insert`, the `post_remove` method must not have
    ///   been called.
    unsafe fn view_value(me: *mut ListLinks<ID>) -> *const Self;

    /// This is called when an item is inserted into a [`List`].
    ///
    /// # Guarantees
    ///
    /// The caller is granted exclusive access to the returned [`ListLinks`] until `post_remove` is
    /// called.
    ///
    /// # Safety
    ///
    /// * The provided pointer must point at a valid value in an [`Arc`].
    /// * Calls to `prepare_to_insert` and `post_remove` on the same value must alternate.
    /// * The caller must own the [`ListArc`] for this value.
    /// * The caller must not give up ownership of the [`ListArc`] unless `post_remove` has been
    ///   called after this call to `prepare_to_insert`.
    ///
    /// [`Arc`]: crate::sync::Arc
    unsafe fn prepare_to_insert(me: *const Self) -> *mut ListLinks<ID>;

    /// This undoes a previous call to `prepare_to_insert`.
    ///
    /// # Guarantees
    ///
    /// The returned pointer is the pointer that was originally passed to `prepare_to_insert`.
    ///
    /// # Safety
    ///
    /// The provided pointer must be the pointer returned by the most recent call to
    /// `prepare_to_insert`.
    unsafe fn post_remove(me: *mut ListLinks<ID>) -> *const Self;
}

#[repr(C)]
#[derive(Copy, Clone)]
struct ListLinksFields {
    next: *mut ListLinksFields,
    prev: *mut ListLinksFields,
}

/// The prev/next pointers for an item in a linked list.
///
/// # Invariants
///
/// The fields are null if and only if this item is not in a list.
#[repr(transparent)]
pub struct ListLinks<const ID: u64 = 0> {
    // This type is `!Unpin` for aliasing reasons as the pointers are part of an intrusive linked
    // list.
    inner: Opaque<ListLinksFields>,
}

// SAFETY: The only way to access/modify the pointers inside of `ListLinks<ID>` is via holding the
// associated `ListArc<T, ID>`. Since that type correctly implements `Send`, it is impossible to
// move this an instance of this type to a different thread if the pointees are `!Send`.
unsafe impl<const ID: u64> Send for ListLinks<ID> {}
// SAFETY: The type is opaque so immutable references to a ListLinks are useless. Therefore, it's
// okay to have immutable access to a ListLinks from several threads at once.
unsafe impl<const ID: u64> Sync for ListLinks<ID> {}

impl<const ID: u64> ListLinks<ID> {
    /// Creates a new initializer for this type.
    pub fn new() -> impl PinInit<Self> {
        // INVARIANT: Pin-init initializers can't be used on an existing `Arc`, so this value will
        // not be constructed in an `Arc` that already has a `ListArc`.
        ListLinks {
            inner: Opaque::new(ListLinksFields {
                prev: ptr::null_mut(),
                next: ptr::null_mut(),
            }),
        }
    }

    /// # Safety
    ///
    /// `me` must be dereferenceable.
    #[inline]
    unsafe fn fields(me: *mut Self) -> *mut ListLinksFields {
        // SAFETY: The caller promises that the pointer is valid.
        unsafe { Opaque::cast_into(ptr::addr_of!((*me).inner)) }
    }

    /// # Safety
    ///
    /// `me` must be dereferenceable.
    #[inline]
    unsafe fn from_fields(me: *mut ListLinksFields) -> *mut Self {
        me.cast()
    }
}

/// Similar to [`ListLinks`], but also contains a pointer to the full value.
///
/// This type can be used instead of [`ListLinks`] to support lists with trait objects.
#[repr(C)]
pub struct ListLinksSelfPtr<T: ?Sized, const ID: u64 = 0> {
    /// The `ListLinks` field inside this value.
    ///
    /// This is public so that it can be used with `impl_has_list_links!`.
    pub inner: ListLinks<ID>,
    // UnsafeCell is not enough here because we use `Opaque::uninit` as a dummy value, and
    // `ptr::null()` doesn't work for `T: ?Sized`.
    self_ptr: Opaque<*const T>,
}

// SAFETY: The fields of a ListLinksSelfPtr can be moved across thread boundaries.
unsafe impl<T: ?Sized + Send, const ID: u64> Send for ListLinksSelfPtr<T, ID> {}
// SAFETY: The type is opaque so immutable references to a ListLinksSelfPtr are useless. Therefore,
// it's okay to have immutable access to a ListLinks from several threads at once.
//
// Note that `inner` being a public field does not prevent this type from being opaque, since
// `inner` is a opaque type.
unsafe impl<T: ?Sized + Sync, const ID: u64> Sync for ListLinksSelfPtr<T, ID> {}

impl<T: ?Sized, const ID: u64> ListLinksSelfPtr<T, ID> {
    /// Creates a new initializer for this type.
    pub fn new() -> impl PinInit<Self> {
        // INVARIANT: Pin-init initializers can't be used on an existing `Arc`, so this value will
        // not be constructed in an `Arc` that already has a `ListArc`.
        Self {
            inner: ListLinks {
                inner: Opaque::new(ListLinksFields {
                    prev: ptr::null_mut(),
                    next: ptr::null_mut(),
                }),
            },
            self_ptr: Opaque::uninit(),
        }
    }

    /// Returns a pointer to the self pointer.
    ///
    /// # Safety
    ///
    /// The provided pointer must point at a valid struct of type `Self`.
    pub unsafe fn raw_get_self_ptr(me: *const Self) -> *const Opaque<*const T> {
        // SAFETY: The caller promises that the pointer is valid.
        unsafe { ptr::addr_of!((*me).self_ptr) }
    }
}

impl<T: ?Sized + ListItem<ID>, const ID: u64> List<T, ID> {
    /// Creates a new empty list.
    pub const fn new() -> Self {
        Self {
            first: ptr::null_mut(),
            _ty: PhantomData,
        }
    }

    /// Returns whether this list is empty.
    pub fn is_empty(&self) -> bool {
        self.first.is_null()
    }

    /// Inserts `item` before `next` in the cycle.
    ///
    /// Returns a pointer to the newly inserted element. Never changes `self.first` unless the list
    /// is empty.
    ///
    /// # Safety
    ///
    /// * `next` must be an element in this list or null.
    /// * if `next` is null, then the list must be empty.
    unsafe fn insert_inner(
        &mut self,
        item: ListArc<T, ID>,
        next: *mut ListLinksFields,
    ) -> *mut ListLinksFields {
        let raw_item = ListArc::into_raw(item);
        // SAFETY:
        // * We just got `raw_item` from a `ListArc`, so it's in an `Arc`.
        // * Since we have ownership of the `ListArc`, `post_remove` must have been called after
        //   the most recent call to `prepare_to_insert`, if any.
        // * We own the `ListArc`.
        // * Removing items from this list is always done using `remove_internal_inner`, which
        //   calls `post_remove` before giving up ownership.
        let list_links = unsafe { T::prepare_to_insert(raw_item) };
        // SAFETY: We have not yet called `post_remove`, so `list_links` is still valid.
        let item = unsafe { ListLinks::fields(list_links) };

        // Check if the list is empty.
        if next.is_null() {
            // SAFETY: The caller just gave us ownership of these fields.
            // INVARIANT: A linked list with one item should be cyclic.
            unsafe {
                (*item).next = item;
                (*item).prev = item;
            }
            self.first = item;
        } else {
            // SAFETY: By the type invariant, this pointer is valid or null. We just checked that
            // it's not null, so it must be valid.
            let prev = unsafe { (*next).prev };
            // SAFETY: Pointers in a linked list are never dangling, and the caller just gave us
            // ownership of the fields on `item`.
            // INVARIANT: This correctly inserts `item` between `prev` and `next`.
            unsafe {
                (*item).next = next;
                (*item).prev = prev;
                (*prev).next = item;
                (*next).prev = item;
            }
        }

        item
    }

    /// Add the provided item to the back of the list.
    pub fn push_back(&mut self, item: ListArc<T, ID>) {
        // SAFETY:
        // * `self.first` is null or in the list.
        // * `self.first` is only null if the list is empty.
        unsafe { self.insert_inner(item, self.first) };
    }

    /// Add the provided item to the front of the list.
    pub fn push_front(&mut self, item: ListArc<T, ID>) {
        // SAFETY:
        // * `self.first` is null or in the list.
        // * `self.first` is only null if the list is empty.
        let new_elem = unsafe { self.insert_inner(item, self.first) };

        // INVARIANT: `new_elem` is in the list because we just inserted it.
        self.first = new_elem;
    }

    /// Removes the last item from this list.
    pub fn pop_back(&mut self) -> Option<ListArc<T, ID>> {
        if self.is_empty() {
            return None;
        }

        // SAFETY: We just checked that the list is not empty.
        let last = unsafe { (*self.first).prev };
        // SAFETY: The last item of this list is in this list.
        Some(unsafe { self.remove_internal(last) })
    }

    /// Removes the first item from this list.
    pub fn pop_front(&mut self) -> Option<ListArc<T, ID>> {
        if self.is_empty() {
            return None;
        }

        // SAFETY: The first item of this list is in this list.
        Some(unsafe { self.remove_internal(self.first) })
    }

    /// Removes the provided item from this list and returns it.
    ///
    /// This returns `None` if the item is not in the list. (Note that by the safety requirements,
    /// this means that the item is not in any list.)
    ///
    /// When using this method, be careful with using `mem::take` on the same list as that may
    /// result in violating the safety requirements of this method.
    ///
    /// # Safety
    ///
    /// `item` must not be in a different linked list (with the same id).
    pub unsafe fn remove(&mut self, item: &T) -> Option<ListArc<T, ID>> {
        // SAFETY: TODO.
        let mut item = unsafe { ListLinks::fields(T::view_links(item)) };
        // SAFETY: The user provided a reference, and reference are never dangling.
        //
        // As for why this is not a data race, there are two cases:
        //
        //  * If `item` is not in any list, then these fields are read-only and null.
        //  * If `item` is in this list, then we have exclusive access to these fields since we
        //    have a mutable reference to the list.
        //
        // In either case, there's no race.
        let ListLinksFields { next, prev } = unsafe { *item };

        debug_assert_eq!(next.is_null(), prev.is_null());
        if !next.is_null() {
            // This is really a no-op, but this ensures that `item` is a raw pointer that was
            // obtained without going through a pointer->reference->pointer conversion roundtrip.
            // This ensures that the list is valid under the more restrictive strict provenance
            // ruleset.
            //
            // SAFETY: We just checked that `next` is not null, and it's not dangling by the
            // list invariants.
            unsafe {
                debug_assert_eq!(item, (*next).prev);
                item = (*next).prev;
            }

            // SAFETY: We just checked that `item` is in a list, so the caller guarantees that it
            // is in this list. The pointers are in the right order.
            Some(unsafe { self.remove_internal_inner(item, next, prev) })
        } else {
            None
        }
    }

    /// Removes the provided item from the list.
    ///
    /// # Safety
    ///
    /// `item` must point at an item in this list.
    unsafe fn remove_internal(&mut self, item: *mut ListLinksFields) -> ListArc<T, ID> {
        // SAFETY: The caller promises that this pointer is not dangling, and there's no data race
        // since we have a mutable reference to the list containing `item`.
        let ListLinksFields { next, prev } = unsafe { *item };
        // SAFETY: The pointers are ok and in the right order.
        unsafe { self.remove_internal_inner(item, next, prev) }
    }

    /// Removes the provided item from the list.
    ///
    /// # Safety
    ///
    /// The `item` pointer must point at an item in this list, and we must have `(*item).next ==
    /// next` and `(*item).prev == prev`.
    unsafe fn remove_internal_inner(
        &mut self,
        item: *mut ListLinksFields,
        next: *mut ListLinksFields,
        prev: *mut ListLinksFields,
    ) -> ListArc<T, ID> {
        // SAFETY: We have exclusive access to the pointers of items in the list, and the prev/next
        // pointers are always valid for items in a list.
        //
        // INVARIANT: There are three cases:
        //  * If the list has at least three items, then after removing the item, `prev` and `next`
        //    will be next to each other.
        //  * If the list has two items, then the remaining item will point at itself.
        //  * If the list has one item, then `next == prev == item`, so these writes have no
        //    effect. The list remains unchanged and `item` is still in the list for now.
        unsafe {
            (*next).prev = prev;
            (*prev).next = next;
        }
        // SAFETY: We have exclusive access to items in the list.
        // INVARIANT: `item` is being removed, so the pointers should be null.
        unsafe {
            (*item).prev = ptr::null_mut();
            (*item).next = ptr::null_mut();
        }
        // INVARIANT: There are three cases:
        //  * If `item` was not the first item, then `self.first` should remain unchanged.
        //  * If `item` was the first item and there is another item, then we just updated
        //    `prev->next` to `next`, which is the new first item, and setting `item->next` to null
        //    did not modify `prev->next`.
        //  * If `item` was the only item in the list, then `prev == item`, and we just set
        //    `item->next` to null, so this correctly sets `first` to null now that the list is
        //    empty.
        if self.first == item {
            // SAFETY: The `prev` pointer is the value that `item->prev` had when it was in this
            // list, so it must be valid. There is no race since `prev` is still in the list and we
            // still have exclusive access to the list.
            self.first = unsafe { (*prev).next };
        }

        // SAFETY: `item` used to be in the list, so it is dereferenceable by the type invariants
        // of `List`.
        let list_links = unsafe { ListLinks::from_fields(item) };
        // SAFETY: Any pointer in the list originates from a `prepare_to_insert` call.
        let raw_item = unsafe { T::post_remove(list_links) };
        // SAFETY: The above call to `post_remove` guarantees that we can recreate the `ListArc`.
        unsafe { ListArc::from_raw(raw_item) }
    }

    /// Moves all items from `other` into `self`.
    ///
    /// The items of `other` are added to the back of `self`, so the last item of `other` becomes
    /// the last item of `self`.
    pub fn push_all_back(&mut self, other: &mut List<T, ID>) {
        // First, we insert the elements into `self`. At the end, we make `other` empty.
        if self.is_empty() {
            // INVARIANT: All of the elements in `other` become elements of `self`.
            self.first = other.first;
        } else if !other.is_empty() {
            let other_first = other.first;
            // SAFETY: The other list is not empty, so this pointer is valid.
            let other_last = unsafe { (*other_first).prev };
            let self_first = self.first;
            // SAFETY: The self list is not empty, so this pointer is valid.
            let self_last = unsafe { (*self_first).prev };

            // SAFETY: We have exclusive access to both lists, so we can update the pointers.
            // INVARIANT: This correctly sets the pointers to merge both lists. We do not need to
            // update `self.first` because the first element of `self` does not change.
            unsafe {
                (*self_first).prev = other_last;
                (*other_last).next = self_first;
                (*self_last).next = other_first;
                (*other_first).prev = self_last;
            }
        }

        // INVARIANT: The other list is now empty, so update its pointer.
        other.first = ptr::null_mut();
    }

    /// Returns a cursor that points before the first element of the list.
    pub fn cursor_front(&mut self) -> Cursor<'_, T, ID> {
        // INVARIANT: `self.first` is in this list.
        Cursor {
            next: self.first,
            list: self,
        }
    }

    /// Returns a cursor that points after the last element in the list.
    pub fn cursor_back(&mut self) -> Cursor<'_, T, ID> {
        // INVARIANT: `next` is allowed to be null.
        Cursor {
            next: core::ptr::null_mut(),
            list: self,
        }
    }

    /// Creates an iterator over the list.
    pub fn iter(&self) -> Iter<'_, T, ID> {
        // INVARIANT: If the list is empty, both pointers are null. Otherwise, both pointers point
        // at the first element of the same list.
        Iter {
            current: self.first,
            stop: self.first,
            _ty: PhantomData,
        }
    }
}

impl<T: ?Sized + ListItem<ID>, const ID: u64> Default for List<T, ID> {
    fn default() -> Self {
        List::new()
    }
}

impl<T: ?Sized + ListItem<ID>, const ID: u64> Drop for List<T, ID> {
    fn drop(&mut self) {
        while let Some(item) = self.pop_front() {
            drop(item);
        }
    }
}

/// An iterator over a [`List`].
///
/// # Invariants
///
/// * There must be a [`List`] that is immutably borrowed for the duration of `'a`.
/// * The `current` pointer is null or points at a value in that [`List`].
/// * The `stop` pointer is equal to the `first` field of that [`List`].
#[derive(Clone)]
pub struct Iter<'a, T: ?Sized + ListItem<ID>, const ID: u64 = 0> {
    current: *mut ListLinksFields,
    stop: *mut ListLinksFields,
    _ty: PhantomData<&'a ListArc<T, ID>>,
}

impl<'a, T: ?Sized + ListItem<ID>, const ID: u64> Iterator for Iter<'a, T, ID> {
    type Item = ArcBorrow<'a, T>;

    fn next(&mut self) -> Option<ArcBorrow<'a, T>> {
        if self.current.is_null() {
            return None;
        }

        let current = self.current;

        // SAFETY: We just checked that `current` is not null, so it is in a list, and hence not
        // dangling. There's no race because the iterator holds an immutable borrow to the list.
        let next = unsafe { (*current).next };
        // INVARIANT: If `current` was the last element of the list, then this updates it to null.
        // Otherwise, we update it to the next element.
        self.current = if next != self.stop {
            next
        } else {
            ptr::null_mut()
        };

        // SAFETY: The `current` pointer points at a value in the list.
        let item = unsafe { T::view_value(ListLinks::from_fields(current)) };
        // SAFETY:
        // * All values in a list are stored in an `Arc`.
        // * The value cannot be removed from the list for the duration of the lifetime annotated
        //   on the returned `ArcBorrow`, because removing it from the list would require mutable
        //   access to the list. However, the `ArcBorrow` is annotated with the iterator's
        //   lifetime, and the list is immutably borrowed for that lifetime.
        // * Values in a list never have a `UniqueArc` reference.
        Some(unsafe { ArcBorrow::from_raw(item) })
    }
}

/// A cursor into a [`List`].
///
/// A cursor always rests between two elements in the list. This means that a cursor has a previous
/// and next element, but no current element. It also means that it's possible to have a cursor
/// into an empty list.
///
/// # Examples
///
/// ```
/// use kernel::prelude::*;
/// use kernel::list::{List, ListArc, ListLinks};
///
/// #[pin_data]
/// struct ListItem {
///     value: u32,
///     #[pin]
///     links: ListLinks,
/// }
///
/// impl ListItem {
///     fn new(value: u32) -> Result<ListArc<Self>> {
///         ListArc::pin_init(try_pin_init!(Self {
///             value,
///             links <- ListLinks::new(),
///         }), GFP_KERNEL)
///     }
/// }
///
/// kernel::list::impl_list_arc_safe! {
///     impl ListArcSafe<0> for ListItem { untracked; }
/// }
/// kernel::list::impl_list_item! {
///     impl ListItem<0> for ListItem { using ListLinks { self.links }; }
/// }
///
/// // Use a cursor to remove the first element with the given value.
/// fn remove_first(list: &mut List<ListItem>, value: u32) -> Option<ListArc<ListItem>> {
///     let mut cursor = list.cursor_front();
///     while let Some(next) = cursor.peek_next() {
///         if next.value == value {
///             return Some(next.remove());
///         }
///         cursor.move_next();
///     }
///     None
/// }
///
/// // Use a cursor to remove the last element with the given value.
/// fn remove_last(list: &mut List<ListItem>, value: u32) -> Option<ListArc<ListItem>> {
///     let mut cursor = list.cursor_back();
///     while let Some(prev) = cursor.peek_prev() {
///         if prev.value == value {
///             return Some(prev.remove());
///         }
///         cursor.move_prev();
///     }
///     None
/// }
///
/// // Use a cursor to remove all elements with the given value. The removed elements are moved to
/// // a new list.
/// fn remove_all(list: &mut List<ListItem>, value: u32) -> List<ListItem> {
///     let mut out = List::new();
///     let mut cursor = list.cursor_front();
///     while let Some(next) = cursor.peek_next() {
///         if next.value == value {
///             out.push_back(next.remove());
///         } else {
///             cursor.move_next();
///         }
///     }
///     out
/// }
///
/// // Use a cursor to insert a value at a specific index. Returns an error if the index is out of
/// // bounds.
/// fn insert_at(list: &mut List<ListItem>, new: ListArc<ListItem>, idx: usize) -> Result {
///     let mut cursor = list.cursor_front();
///     for _ in 0..idx {
///         if !cursor.move_next() {
///             return Err(EINVAL);
///         }
///     }
///     cursor.insert_next(new);
///     Ok(())
/// }
///
/// // Merge two sorted lists into a single sorted list.
/// fn merge_sorted(list: &mut List<ListItem>, merge: List<ListItem>) {
///     let mut cursor = list.cursor_front();
///     for to_insert in merge {
///         while let Some(next) = cursor.peek_next() {
///             if to_insert.value < next.value {
///                 break;
///             }
///             cursor.move_next();
///         }
///         cursor.insert_prev(to_insert);
///     }
/// }
///
/// let mut list = List::new();
/// list.push_back(ListItem::new(14)?);
/// list.push_back(ListItem::new(12)?);
/// list.push_back(ListItem::new(10)?);
/// list.push_back(ListItem::new(12)?);
/// list.push_back(ListItem::new(15)?);
/// list.push_back(ListItem::new(14)?);
/// assert_eq!(remove_all(&mut list, 12).iter().count(), 2);
/// // [14, 10, 15, 14]
/// assert!(remove_first(&mut list, 14).is_some());
/// // [10, 15, 14]
/// insert_at(&mut list, ListItem::new(12)?, 2)?;
/// // [10, 15, 12, 14]
/// assert!(remove_last(&mut list, 15).is_some());
/// // [10, 12, 14]
///
/// let mut list2 = List::new();
/// list2.push_back(ListItem::new(11)?);
/// list2.push_back(ListItem::new(13)?);
/// merge_sorted(&mut list, list2);
///
/// let mut items = list.into_iter();
/// assert_eq!(items.next().ok_or(EINVAL)?.value, 10);
/// assert_eq!(items.next().ok_or(EINVAL)?.value, 11);
/// assert_eq!(items.next().ok_or(EINVAL)?.value, 12);
/// assert_eq!(items.next().ok_or(EINVAL)?.value, 13);
/// assert_eq!(items.next().ok_or(EINVAL)?.value, 14);
/// assert!(items.next().is_none());
/// # Result::<(), Error>::Ok(())
/// ```
///
/// # Invariants
///
/// The `next` pointer is null or points a value in `list`.
pub struct Cursor<'a, T: ?Sized + ListItem<ID>, const ID: u64 = 0> {
    list: &'a mut List<T, ID>,
    /// Points at the element after this cursor, or null if the cursor is after the last element.
    next: *mut ListLinksFields,
}

impl<'a, T: ?Sized + ListItem<ID>, const ID: u64> Cursor<'a, T, ID> {
    /// Returns a pointer to the element before the cursor.
    ///
    /// Returns null if there is no element before the cursor.
    fn prev_ptr(&self) -> *mut ListLinksFields {
        let mut next = self.next;
        let first = self.list.first;
        if next == first {
            // We are before the first element.
            return core::ptr::null_mut();
        }

        if next.is_null() {
            // We are after the last element, so we need a pointer to the last element, which is
            // the same as `(*first).prev`.
            next = first;
        }

        // SAFETY: `next` can't be null, because then `first` must also be null, but in that case
        // we would have exited at the `next == first` check. Thus, `next` is an element in the
        // list, so we can access its `prev` pointer.
        unsafe { (*next).prev }
    }

    /// Access the element after this cursor.
    pub fn peek_next(&mut self) -> Option<CursorPeek<'_, 'a, T, true, ID>> {
        if self.next.is_null() {
            return None;
        }

        // INVARIANT:
        // * We just checked that `self.next` is non-null, so it must be in `self.list`.
        // * `ptr` is equal to `self.next`.
        Some(CursorPeek {
            ptr: self.next,
            cursor: self,
        })
    }

    /// Access the element before this cursor.
    pub fn peek_prev(&mut self) -> Option<CursorPeek<'_, 'a, T, false, ID>> {
        let prev = self.prev_ptr();

        if prev.is_null() {
            return None;
        }

        // INVARIANT:
        // * We just checked that `prev` is non-null, so it must be in `self.list`.
        // * `self.prev_ptr()` never returns `self.next`.
        Some(CursorPeek {
            ptr: prev,
            cursor: self,
        })
    }

    /// Move the cursor one element forward.
    ///
    /// If the cursor is after the last element, then this call does nothing. This call returns
    /// `true` if the cursor's position was changed.
    pub fn move_next(&mut self) -> bool {
        if self.next.is_null() {
            return false;
        }

        // SAFETY: `self.next` is an element in the list and we borrow the list mutably, so we can
        // access the `next` field.
        let mut next = unsafe { (*self.next).next };

        if next == self.list.first {
            next = core::ptr::null_mut();
        }

        // INVARIANT: `next` is either null or the next element after an element in the list.
        self.next = next;
        true
    }

    /// Move the cursor one element backwards.
    ///
    /// If the cursor is before the first element, then this call does nothing. This call returns
    /// `true` if the cursor's position was changed.
    pub fn move_prev(&mut self) -> bool {
        if self.next == self.list.first {
            return false;
        }

        // INVARIANT: `prev_ptr()` always returns a pointer that is null or in the list.
        self.next = self.prev_ptr();
        true
    }

    /// Inserts an element where the cursor is pointing and get a pointer to the new element.
    fn insert_inner(&mut self, item: ListArc<T, ID>) -> *mut ListLinksFields {
        let ptr = if self.next.is_null() {
            self.list.first
        } else {
            self.next
        };
        // SAFETY:
        // * `ptr` is an element in the list or null.
        // * if `ptr` is null, then `self.list.first` is null so the list is empty.
        let item = unsafe { self.list.insert_inner(item, ptr) };
        if self.next == self.list.first {
            // INVARIANT: We just inserted `item`, so it's a member of list.
            self.list.first = item;
        }
        item
    }

    /// Insert an element at this cursor's location.
    pub fn insert(mut self, item: ListArc<T, ID>) {
        // This is identical to `insert_prev`, but consumes the cursor. This is helpful because it
        // reduces confusion when the last operation on the cursor is an insertion; in that case,
        // you just want to insert the element at the cursor, and it is confusing that the call
        // involves the word prev or next.
        self.insert_inner(item);
    }

    /// Inserts an element after this cursor.
    ///
    /// After insertion, the new element will be after the cursor.
    pub fn insert_next(&mut self, item: ListArc<T, ID>) {
        self.next = self.insert_inner(item);
    }

    /// Inserts an element before this cursor.
    ///
    /// After insertion, the new element will be before the cursor.
    pub fn insert_prev(&mut self, item: ListArc<T, ID>) {
        self.insert_inner(item);
    }

    /// Remove the next element from the list.
    pub fn remove_next(&mut self) -> Option<ListArc<T, ID>> {
        self.peek_next().map(|v| v.remove())
    }

    /// Remove the previous element from the list.
    pub fn remove_prev(&mut self) -> Option<ListArc<T, ID>> {
        self.peek_prev().map(|v| v.remove())
    }
}

/// References the element in the list next to the cursor.
///
/// # Invariants
///
/// * `ptr` is an element in `self.cursor.list`.
/// * `ISNEXT == (self.ptr == self.cursor.next)`.
pub struct CursorPeek<'a, 'b, T: ?Sized + ListItem<ID>, const ISNEXT: bool, const ID: u64> {
    cursor: &'a mut Cursor<'b, T, ID>,
    ptr: *mut ListLinksFields,
}

impl<'a, 'b, T: ?Sized + ListItem<ID>, const ISNEXT: bool, const ID: u64>
    CursorPeek<'a, 'b, T, ISNEXT, ID>
{
    /// Remove the element from the list.
    pub fn remove(self) -> ListArc<T, ID> {
        if ISNEXT {
            self.cursor.move_next();
        }

        // INVARIANT: `self.ptr` is not equal to `self.cursor.next` due to the above `move_next`
        // call.
        // SAFETY: By the type invariants of `Self`, `next` is not null, so `next` is an element of
        // `self.cursor.list` by the type invariants of `Cursor`.
        unsafe { self.cursor.list.remove_internal(self.ptr) }
    }

    /// Access this value as an [`ArcBorrow`].
    pub fn arc(&self) -> ArcBorrow<'_, T> {
        // SAFETY: `self.ptr` points at an element in `self.cursor.list`.
        let me = unsafe { T::view_value(ListLinks::from_fields(self.ptr)) };
        // SAFETY:
        // * All values in a list are stored in an `Arc`.
        // * The value cannot be removed from the list for the duration of the lifetime annotated
        //   on the returned `ArcBorrow`, because removing it from the list would require mutable
        //   access to the `CursorPeek`, the `Cursor` or the `List`. However, the `ArcBorrow` holds
        //   an immutable borrow on the `CursorPeek`, which in turn holds a mutable borrow on the
        //   `Cursor`, which in turn holds a mutable borrow on the `List`, so any such mutable
        //   access requires first releasing the immutable borrow on the `CursorPeek`.
        // * Values in a list never have a `UniqueArc` reference, because the list has a `ListArc`
        //   reference, and `UniqueArc` references must be unique.
        unsafe { ArcBorrow::from_raw(me) }
    }
}

impl<'a, 'b, T: ?Sized + ListItem<ID>, const ISNEXT: bool, const ID: u64> core::ops::Deref
    for CursorPeek<'a, 'b, T, ISNEXT, ID>
{
    // If you change the `ptr` field to have type `ArcBorrow<'a, T>`, it might seem like you could
    // get rid of the `CursorPeek::arc` method and change the deref target to `ArcBorrow<'a, T>`.
    // However, that doesn't work because 'a is too long. You could obtain an `ArcBorrow<'a, T>`
    // and then call `CursorPeek::remove` without giving up the `ArcBorrow<'a, T>`, which would be
    // unsound.
    type Target = T;

    fn deref(&self) -> &T {
        // SAFETY: `self.ptr` points at an element in `self.cursor.list`.
        let me = unsafe { T::view_value(ListLinks::from_fields(self.ptr)) };

        // SAFETY: The value cannot be removed from the list for the duration of the lifetime
        // annotated on the returned `&T`, because removing it from the list would require mutable
        // access to the `CursorPeek`, the `Cursor` or the `List`. However, the `&T` holds an
        // immutable borrow on the `CursorPeek`, which in turn holds a mutable borrow on the
        // `Cursor`, which in turn holds a mutable borrow on the `List`, so any such mutable access
        // requires first releasing the immutable borrow on the `CursorPeek`.
        unsafe { &*me }
    }
}

impl<'a, T: ?Sized + ListItem<ID>, const ID: u64> FusedIterator for Iter<'a, T, ID> {}

impl<'a, T: ?Sized + ListItem<ID>, const ID: u64> IntoIterator for &'a List<T, ID> {
    type IntoIter = Iter<'a, T, ID>;
    type Item = ArcBorrow<'a, T>;

    fn into_iter(self) -> Iter<'a, T, ID> {
        self.iter()
    }
}

/// An owning iterator into a [`List`].
pub struct IntoIter<T: ?Sized + ListItem<ID>, const ID: u64 = 0> {
    list: List<T, ID>,
}

impl<T: ?Sized + ListItem<ID>, const ID: u64> Iterator for IntoIter<T, ID> {
    type Item = ListArc<T, ID>;

    fn next(&mut self) -> Option<ListArc<T, ID>> {
        self.list.pop_front()
    }
}

impl<T: ?Sized + ListItem<ID>, const ID: u64> FusedIterator for IntoIter<T, ID> {}

impl<T: ?Sized + ListItem<ID>, const ID: u64> DoubleEndedIterator for IntoIter<T, ID> {
    fn next_back(&mut self) -> Option<ListArc<T, ID>> {
        self.list.pop_back()
    }
}

impl<T: ?Sized + ListItem<ID>, const ID: u64> IntoIterator for List<T, ID> {
    type IntoIter = IntoIter<T, ID>;
    type Item = ListArc<T, ID>;

    fn into_iter(self) -> IntoIter<T, ID> {
        IntoIter { list: self }
    }
}
