use core::num::NonZeroUsize;

use crate::{SyscallRegister, ThinWrapped};

macro_rules! numeric_impl {
    ($($ty:ident),+ $(,)?) => {
        $(
            unsafe impl ThinWrapped for $ty {}

            impl SyscallRegister for $ty {
                fn into_syscall_register(self) -> usize {
                    self as _
                }

                fn from_syscall_register(value: usize) -> Self {
                    value as _
                }
            }
        )+
    };
}

numeric_impl!(u8, u16, u32);
numeric_impl!(i8, i16, i32);

#[cfg(any(target_pointer_width = "64", rust_analyzer))]
numeric_impl!(u64, i64);

#[cfg(any(target_pointer_width = "32", rust_analyzer))]
impl crate::SyscallFatRegister for u64 {
    fn as_syscall_meta(&self) -> usize {
        todo!()
    }

    fn as_syscall_data(&self) -> usize {
        todo!()
    }

    fn from_syscall_registers(_meta: usize, _data: usize) -> Self {
        todo!()
    }
}

#[cfg(any(target_pointer_width = "32", rust_analyzer))]
impl crate::SyscallFatRegister for u32 {
    fn as_syscall_meta(&self) -> usize {
        todo!()
    }

    fn as_syscall_data(&self) -> usize {
        todo!()
    }

    fn from_syscall_registers(_meta: usize, _data: usize) -> Self {
        todo!()
    }
}

unsafe impl ThinWrapped for () {}

impl SyscallRegister for NonZeroUsize {
    fn from_syscall_register(value: usize) -> Self {
        unsafe { Self::new_unchecked(value) }
    }

    fn into_syscall_register(self) -> usize {
        self.into()
    }
}

impl SyscallRegister for () {
    fn into_syscall_register(self) -> usize {
        0
    }

    fn from_syscall_register(_value: usize) -> Self {}
}

impl SyscallRegister for ! {
    fn from_syscall_register(_value: usize) -> Self {
        unreachable!()
    }

    fn into_syscall_register(self) -> usize {
        self
    }
}
