// Copyright 2025 Red Hat, Inc.
// Author(s): Paolo Bonzini <pbonzini@redhat.com>
// SPDX-License-Identifier: GPL-2.0-or-later

use std::{
    fmt,
    mem::size_of,
    ptr::{self, addr_of, NonNull},
    sync::{Arc, Mutex},
};

use bql::prelude::*;
use common::Zeroable;

use crate::{
    bindings, vmstate_fields_ref, vmstate_of, InvalidError, VMState, VMStateDescriptionBuilder,
};

/// Enables QEMU migration support even when a type is wrapped with
/// synchronization primitives (like `Mutex`) that the C migration
/// code cannot directly handle. The trait provides methods to
/// extract essential state for migration and restore it after
/// migration completes.
///
/// On top of extracting data from synchronization wrappers during save
/// and restoring it during load, it's also possible to use `ToMigrationState`
/// to convert runtime representations to migration-safe formats.
///
/// # Examples
///
/// ```
/// use bql::BqlCell;
/// use migration::{InvalidError, ToMigrationState, VMState};
/// # use migration::VMStateField;
///
/// # #[derive(Debug, PartialEq, Eq)]
/// struct DeviceState {
///     counter: BqlCell<u32>,
///     enabled: bool,
/// }
///
/// # #[derive(Debug)]
/// #[derive(Default)]
/// struct DeviceMigrationState {
///     counter: u32,
///     enabled: bool,
/// }
///
/// # unsafe impl VMState for DeviceMigrationState {
/// #     const BASE: VMStateField = ::common::Zeroable::ZERO;
/// # }
/// impl ToMigrationState for DeviceState {
///     type Migrated = DeviceMigrationState;
///
///     fn snapshot_migration_state(
///         &self,
///         target: &mut Self::Migrated,
///     ) -> Result<(), InvalidError> {
///         target.counter = self.counter.get();
///         target.enabled = self.enabled;
///         Ok(())
///     }
///
///     fn restore_migrated_state_mut(
///         &mut self,
///         source: Self::Migrated,
///         _version_id: u8,
///     ) -> Result<(), InvalidError> {
///         self.counter.set(source.counter);
///         self.enabled = source.enabled;
///         Ok(())
///     }
/// }
/// # bql::start_test();
/// # let dev = DeviceState { counter: 10.into(), enabled: true };
/// # let mig = dev.to_migration_state().unwrap();
/// # assert!(matches!(*mig, DeviceMigrationState { counter: 10, enabled: true }));
/// # let mut dev2 = DeviceState { counter: 42.into(), enabled: false };
/// # dev2.restore_migrated_state_mut(*mig, 1).unwrap();
/// # assert_eq!(dev2, dev);
/// ```
///
/// More commonly, the trait is derived through the
/// [`derive(ToMigrationState)`](qemu_macros::ToMigrationState) procedural
/// macro.
pub trait ToMigrationState {
    /// The type used to represent the migrated state.
    type Migrated: Default + VMState;

    /// Capture the current state into a migration-safe format, failing
    /// if the state cannot be migrated.
    fn snapshot_migration_state(&self, target: &mut Self::Migrated) -> Result<(), InvalidError>;

    /// Restores state from a migrated representation, failing if the
    /// state cannot be restored.
    fn restore_migrated_state_mut(
        &mut self,
        source: Self::Migrated,
        version_id: u8,
    ) -> Result<(), InvalidError>;

    /// Convenience method to combine allocation and state capture
    /// into a single operation.
    fn to_migration_state(&self) -> Result<Box<Self::Migrated>, InvalidError> {
        let mut migrated = Box::<Self::Migrated>::default();
        self.snapshot_migration_state(&mut migrated)?;
        Ok(migrated)
    }
}

// Implementations for primitive types.  Do not use a blanket implementation
// for all Copy types, because [T; N] is Copy if T is Copy; that would conflict
// with the below implementation for arrays.
macro_rules! impl_for_primitive {
    ($($t:ty),*) => {
        $(
            impl ToMigrationState for $t {
                type Migrated = Self;

                fn snapshot_migration_state(
                    &self,
                    target: &mut Self::Migrated,
                ) -> Result<(), InvalidError> {
                    *target = *self;
                    Ok(())
                }

                fn restore_migrated_state_mut(
                    &mut self,
                    source: Self::Migrated,
                    _version_id: u8,
                ) -> Result<(), InvalidError> {
                    *self = source;
                    Ok(())
                }
            }
        )*
    };
}

impl_for_primitive!(u8, u16, u32, u64, i8, i16, i32, i64, bool);

impl ToMigrationState for util::timer::Timer {
    type Migrated = i64;

    fn snapshot_migration_state(&self, target: &mut i64) -> Result<(), InvalidError> {
        // SAFETY: as_ptr() is unsafe to ensure that the caller reasons about
        // the pinning of the data inside the Opaque<>.  Here all we do is
        // access a field.
        *target = self.expire_time_ns().unwrap_or(-1);
        Ok(())
    }

    fn restore_migrated_state_mut(
        &mut self,
        source: Self::Migrated,
        version_id: u8,
    ) -> Result<(), InvalidError> {
        self.restore_migrated_state(source, version_id)
    }
}

impl<T: ToMigrationState, const N: usize> ToMigrationState for [T; N]
where
    [T::Migrated; N]: Default,
{
    type Migrated = [T::Migrated; N];

    fn snapshot_migration_state(&self, target: &mut Self::Migrated) -> Result<(), InvalidError> {
        for (item, target_item) in self.iter().zip(target.iter_mut()) {
            item.snapshot_migration_state(target_item)?;
        }
        Ok(())
    }

    fn restore_migrated_state_mut(
        &mut self,
        source: Self::Migrated,
        version_id: u8,
    ) -> Result<(), InvalidError> {
        for (item, source_item) in self.iter_mut().zip(source) {
            item.restore_migrated_state_mut(source_item, version_id)?;
        }
        Ok(())
    }
}

impl<T: ToMigrationState> ToMigrationState for Mutex<T> {
    type Migrated = T::Migrated;

    fn snapshot_migration_state(&self, target: &mut Self::Migrated) -> Result<(), InvalidError> {
        self.lock().unwrap().snapshot_migration_state(target)
    }

    fn restore_migrated_state_mut(
        &mut self,
        source: Self::Migrated,
        version_id: u8,
    ) -> Result<(), InvalidError> {
        self.get_mut()
            .unwrap()
            .restore_migrated_state_mut(source, version_id)
    }
}

impl<T: ToMigrationState> ToMigrationState for BqlRefCell<T> {
    type Migrated = T::Migrated;

    fn snapshot_migration_state(&self, target: &mut Self::Migrated) -> Result<(), InvalidError> {
        self.borrow().snapshot_migration_state(target)
    }

    fn restore_migrated_state_mut(
        &mut self,
        source: Self::Migrated,
        version_id: u8,
    ) -> Result<(), InvalidError> {
        self.get_mut()
            .restore_migrated_state_mut(source, version_id)
    }
}

/// Extension trait for types that support migration state restoration
/// through interior mutability.
///
/// This trait extends [`ToMigrationState`] for types that can restore
/// their state without requiring mutable access. While user structs
/// will generally use `ToMigrationState`, the device will have multiple
/// references and therefore the device struct has to employ an interior
/// mutability wrapper like [`Mutex`] or [`BqlRefCell`].
///
/// Anything that implements this trait can in turn be used within
/// [`Migratable<T>`], which makes no assumptions on how to achieve mutable
/// access to the runtime state.
///
/// # Examples
///
/// ```
/// use std::sync::Mutex;
///
/// use migration::ToMigrationStateShared;
///
/// let device_state = Mutex::new(42);
/// // Can restore without &mut access
/// device_state.restore_migrated_state(100, 1).unwrap();
/// assert_eq!(*device_state.lock().unwrap(), 100);
/// ```
pub trait ToMigrationStateShared: ToMigrationState {
    /// Restores state from a migrated representation to an interior-mutable
    /// object.  Similar to `restore_migrated_state_mut`, but requires a
    /// shared reference; therefore it can be used to restore a device's
    /// state even though devices have multiple references to them.
    fn restore_migrated_state(
        &self,
        source: Self::Migrated,
        version_id: u8,
    ) -> Result<(), InvalidError>;
}

impl ToMigrationStateShared for util::timer::Timer {
    fn restore_migrated_state(&self, source: i64, _version_id: u8) -> Result<(), InvalidError> {
        if source >= 0 {
            self.modify_ns(source as u64);
        } else {
            self.delete();
        }
        Ok(())
    }
}

impl<T: ToMigrationStateShared, const N: usize> ToMigrationStateShared for [T; N]
where
    [T::Migrated; N]: Default,
{
    fn restore_migrated_state(
        &self,
        source: Self::Migrated,
        version_id: u8,
    ) -> Result<(), InvalidError> {
        for (item, source_item) in self.iter().zip(source) {
            item.restore_migrated_state(source_item, version_id)?;
        }
        Ok(())
    }
}

// Arc requires the contained object to be interior-mutable
impl<T: ToMigrationStateShared> ToMigrationState for Arc<T> {
    type Migrated = T::Migrated;

    fn snapshot_migration_state(&self, target: &mut Self::Migrated) -> Result<(), InvalidError> {
        (**self).snapshot_migration_state(target)
    }

    fn restore_migrated_state_mut(
        &mut self,
        source: Self::Migrated,
        version_id: u8,
    ) -> Result<(), InvalidError> {
        (**self).restore_migrated_state(source, version_id)
    }
}

impl<T: ToMigrationStateShared> ToMigrationStateShared for Arc<T> {
    fn restore_migrated_state(
        &self,
        source: Self::Migrated,
        version_id: u8,
    ) -> Result<(), InvalidError> {
        (**self).restore_migrated_state(source, version_id)
    }
}

// Interior-mutable types.  Note how they only require ToMigrationState for
// the inner type!

impl<T: ToMigrationState> ToMigrationStateShared for Mutex<T> {
    fn restore_migrated_state(
        &self,
        source: Self::Migrated,
        version_id: u8,
    ) -> Result<(), InvalidError> {
        self.lock()
            .unwrap()
            .restore_migrated_state_mut(source, version_id)
    }
}

impl<T: ToMigrationState> ToMigrationStateShared for BqlRefCell<T> {
    fn restore_migrated_state(
        &self,
        source: Self::Migrated,
        version_id: u8,
    ) -> Result<(), InvalidError> {
        self.borrow_mut()
            .restore_migrated_state_mut(source, version_id)
    }
}

/// A wrapper that enables QEMU migration for types with shared state.
///
/// `Migratable<T>` provides a bridge between Rust types that use interior
/// mutability (like `Mutex<T>`) and QEMU's C-based migration infrastructure.
/// It manages the lifecycle of migration state and provides automatic
/// conversion between runtime and migration representations.
///
/// ```
/// # use std::sync::Mutex;
/// # use migration::{Migratable, ToMigrationState, VMState, VMStateField};
///
/// #[derive(ToMigrationState)]
/// pub struct DeviceRegs {
///     status: u32,
/// }
/// # unsafe impl VMState for DeviceRegsMigration {
/// #     const BASE: VMStateField = ::common::Zeroable::ZERO;
/// # }
///
/// pub struct SomeDevice {
///     // ...
///     registers: Migratable<Mutex<DeviceRegs>>,
/// }
/// ```
#[repr(C)]
pub struct Migratable<T: ToMigrationStateShared> {
    /// Pointer to migration state, valid only during migration operations.
    /// C vmstate does not support NULL pointers, so no `Option<Box<>>`.
    migration_state: BqlCell<*mut T::Migrated>,

    /// The runtime state that can be accessed during normal operation
    runtime_state: T,
}

// SAFETY: the migration_state asserts via `BqlCell` that the BQL is taken.
unsafe impl<T: ToMigrationStateShared + Sync> Sync for Migratable<T> {}

impl<T: ToMigrationStateShared> std::ops::Deref for Migratable<T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &self.runtime_state
    }
}

impl<T: ToMigrationStateShared> std::ops::DerefMut for Migratable<T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.runtime_state
    }
}

impl<T: ToMigrationStateShared> Migratable<T> {
    /// Creates a new `Migratable` wrapper around the given runtime state.
    ///
    /// # Returns
    /// A new `Migratable` instance ready for use and migration
    pub fn new(runtime_state: T) -> Self {
        Self {
            migration_state: BqlCell::new(ptr::null_mut()),
            runtime_state,
        }
    }

    fn pre_save(&self) -> Result<(), InvalidError> {
        let state = self.runtime_state.to_migration_state()?;
        self.migration_state.set(Box::into_raw(state));
        Ok(())
    }

    fn post_save(&self) {
        let _ = unsafe { Box::from_raw(self.migration_state.replace(ptr::null_mut())) };
    }

    fn pre_load(&self) -> Result<(), InvalidError> {
        self.migration_state
            .set(Box::into_raw(Box::<T::Migrated>::default()));
        Ok(())
    }

    fn post_load(&self, version_id: u8) -> Result<(), InvalidError> {
        let state = unsafe { Box::from_raw(self.migration_state.replace(ptr::null_mut())) };
        self.runtime_state
            .restore_migrated_state(*state, version_id)
    }
}

impl<T: ToMigrationStateShared + fmt::Debug> fmt::Debug for Migratable<T>
where
    T::Migrated: fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let mut struct_f = f.debug_struct("Migratable");
        struct_f.field("runtime_state", &self.runtime_state);

        let state = NonNull::new(self.migration_state.get()).map(|x| unsafe { x.as_ref() });
        struct_f.field("migration_state", &state);
        struct_f.finish()
    }
}

impl<T: ToMigrationStateShared + Default> Default for Migratable<T> {
    fn default() -> Self {
        Self::new(T::default())
    }
}

impl<T: 'static + ToMigrationStateShared> Migratable<T> {
    const FIELD: bindings::VMStateField = vmstate_of!(Self, migration_state);

    const FIELDS: &[bindings::VMStateField] = vmstate_fields_ref! {
        Migratable::<T>::FIELD
    };

    // All Migratable<T> instances share the same name. This is fine because
    // Migratable<T> is always a field within a VMSD. The parent VMSD has the
    // different name to distinguish child Migratable<T>.
    const VMSD: &'static bindings::VMStateDescription = VMStateDescriptionBuilder::<Self>::new()
        .name(c"migratable-wrapper")
        .version_id(1)
        .minimum_version_id(1)
        .pre_save(&Self::pre_save)
        .pre_load(&Self::pre_load)
        .post_save(&Self::post_save)
        .post_load(&Self::post_load)
        .fields(Self::FIELDS)
        .build()
        .as_ref();
}

unsafe impl<T: 'static + ToMigrationStateShared> VMState for Migratable<T> {
    const BASE: bindings::VMStateField = {
        bindings::VMStateField {
            vmsd: addr_of!(*Self::VMSD),
            size: size_of::<Self>(),
            flags: bindings::VMStateFlags::VMS_STRUCT,
            ..Zeroable::ZERO
        }
    };
}
