use core::{
    ffi::{c_int, c_uint, c_ulong, c_void},
    ptr::NonNull,
    sync::atomic::{AtomicBool, AtomicU32},
};

#[cfg(any(target_pointer_width = "64", rust_analyzer))]
mod bits64;
#[cfg(any(target_pointer_width = "64", rust_analyzer))]
pub use bits64::*;

#[cfg(any(target_pointer_width = "32", rust_analyzer))]
mod bits32;
#[cfg(any(target_pointer_width = "32", rust_analyzer))]
pub use bits32::*;

pub type pid_t = i32;
pub type uid_t = i32;
pub type gid_t = i32;
pub type id_t = i32;

pub type dev_t = u32;

pub type clockid_t = i32;
pub type timer_t = i32;

pub type mode_t = c_int;

pub type blkcnt_t = i64;
pub type blksize_t = c_ulong;
pub type nlink_t = u64;

pub type fsblkcnt_t = u64;
pub type fsfilcnt_t = u64;
pub type ino_t = u64;

pub type clock_t = u64;

pub type u_int = c_uint;
pub type u_long = c_ulong;

#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
#[repr(transparent)]
pub struct time_t(pub i64);

pub type suseconds_t = c_ulong;

impl time_t {
    pub const INVALID: Self = Self(i64::MAX);
}

// pthread types

#[repr(C)]
pub struct pthread_attr_t {
    pub stack: Option<NonNull<c_void>>,
    pub stack_size: usize,
}

#[repr(C)]
pub struct pthread_barrier_t {
    pub(crate) __state: AtomicU32,
    pub(crate) __limit: u32,
}
#[repr(C)]
pub struct pthread_barrierattr_t {}

#[repr(C)]
pub struct pthread_cond_t {
    pub(crate) __read: AtomicU32,
    pub(crate) __write: AtomicU32,
}
#[repr(C)]
pub struct pthread_condattr_t {}

pub type pthread_key_t = usize;

#[repr(C)]
pub struct pthread_mutex_t {
    pub(crate) __mode: c_int,
    pub(crate) __state: AtomicU32,
    pub(crate) __recursion: AtomicU32,
}
#[repr(C)]
pub struct pthread_mutexattr_t {
    pub(crate) __mode: c_int,
}

#[repr(C)]
pub struct pthread_once_t {
    pub(crate) __state: AtomicBool,
}

#[repr(C)]
pub struct pthread_rwlock_t {
    __dummy: c_int,
}
pub struct pthread_rwlockattr_t {}

pub struct pthread_spinlock_t {}

pub type pthread_t = u32;
