use libc::{c_char, c_int, c_void, timeval};

use std::{
    cmp::Ordering, ffi::CStr, mem, ptr, sync::Arc, sync::Mutex, sync::Once, sync::OnceLock,
    time::Duration,
};

#[cfg(unix)]
use std::os::unix::io::RawFd;

use crate::hotplug::{Hotplug, HotplugBuilder, Registration};
use crate::{device_handle::DeviceHandle, device_list::DeviceList, error};
use libusb1_sys::{constants::*, *};

#[cfg(windows)]
type Seconds = ::libc::c_long;
#[cfg(windows)]
type MicroSeconds = ::libc::c_long;

#[cfg(not(windows))]
type Seconds = ::libc::time_t;
#[cfg(not(windows))]
type MicroSeconds = ::libc::suseconds_t;

#[derive(Copy, Clone, Eq, PartialEq, Default)]
pub struct GlobalContext {}

/// A `libusb` context.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Context {
    context: Arc<ContextInner>,
}

#[derive(Debug, Eq, PartialEq)]
struct ContextInner {
    inner: ptr::NonNull<libusb_context>,
}

impl Drop for ContextInner {
    /// Closes the `libusb` context.
    fn drop(&mut self) {
        unsafe {
            libusb_exit(self.inner.as_ptr());
        }
    }
}

unsafe impl Sync for Context {}
unsafe impl Send for Context {}

type LogCallback = Box<dyn Fn(LogLevel, String)>;

struct LogCallbackMap {
    map: std::collections::HashMap<*mut libusb_context, LogCallback>,
}

unsafe impl Sync for LogCallbackMap {}
unsafe impl Send for LogCallbackMap {}

impl LogCallbackMap {
    pub fn new() -> Self {
        Self {
            map: std::collections::HashMap::new(),
        }
    }
}

static LOG_CALLBACK_MAP: OnceLock<Mutex<LogCallbackMap>> = OnceLock::new();

extern "system" fn static_log_callback(
    context: *mut libusb_context,
    level: c_int,
    text: *mut c_void,
) {
    if let Some(log_callback_map) = LOG_CALLBACK_MAP.get() {
        if let Ok(locked_table) = log_callback_map.lock() {
            if let Some(logger) = locked_table.map.get(&context) {
                let c_str: &CStr = unsafe { CStr::from_ptr(text as *const c_char) };
                let str_slice: &str = c_str.to_str().unwrap_or("");
                let log_message = str_slice.to_owned();

                logger(LogLevel::from_c_int(level), log_message);
            }
        }
    }
}

pub trait UsbContext: Clone + Sized + Send + Sync {
    /// Get the raw libusb_context pointer, for advanced use in unsafe code.
    fn as_raw(&self) -> *mut libusb_context;

    /// Returns a list of the current USB devices.
    fn devices(&self) -> crate::Result<DeviceList<Self>> {
        DeviceList::new_with_context(self.clone())
    }

    /// Convenience function to open a device by its vendor ID and product ID.
    ///
    /// This function is provided as a convenience for building prototypes without having to
    /// iterate a [`DeviceList`](struct.DeviceList.html). It is not meant for production
    /// applications.
    ///
    /// Returns a device handle for the first device found matching `vendor_id` and `product_id`.
    /// On error, or if the device could not be found, it returns `None`.
    fn open_device_with_vid_pid(
        &self,
        vendor_id: u16,
        product_id: u16,
    ) -> Option<DeviceHandle<Self>> {
        let handle =
            unsafe { libusb_open_device_with_vid_pid(self.as_raw(), vendor_id, product_id) };
        let ptr = std::ptr::NonNull::new(handle)?;
        Some(unsafe { DeviceHandle::from_libusb(self.clone(), ptr) })
    }

    /// Opens the device with a pre-opened file descriptor.
    ///
    /// This is UNIX-only and platform-specific. It is currently working with
    /// Linux/Android, but might work with other systems in the future.
    ///
    /// Note: This function does not take ownership of the specified file
    /// descriptor. The caller has the responsibility of keeping it opened for
    /// as long as the device handle.
    #[cfg(unix)]
    #[doc(alias = "libusb_wrap_sys_device")]
    unsafe fn open_device_with_fd(&self, fd: RawFd) -> crate::Result<DeviceHandle<Self>> {
        let mut handle = mem::MaybeUninit::<*mut libusb_device_handle>::uninit();

        match libusb_wrap_sys_device(self.as_raw(), fd as _, handle.as_mut_ptr()) {
            0 => {
                let ptr =
                    std::ptr::NonNull::new(handle.assume_init()).ok_or(crate::Error::NoDevice)?;

                Ok(DeviceHandle::from_libusb(self.clone(), ptr))
            }
            err => Err(error::from_libusb(err)),
        }
    }

    /// Sets the log level of a `libusb` for context.
    fn set_log_level(&mut self, level: LogLevel) {
        unsafe {
            libusb_set_debug(self.as_raw(), level.as_c_int());
        }
    }

    fn set_log_callback(&mut self, log_callback: LogCallback, mode: LogCallbackMode) {
        let log_callback_map = LOG_CALLBACK_MAP.get_or_init(|| Mutex::new(LogCallbackMap::new()));
        if let Ok(mut locked_table) = log_callback_map.lock() {
            locked_table.map.insert(self.as_raw(), log_callback);
        }

        unsafe {
            libusb_set_log_cb(self.as_raw(), Some(static_log_callback), mode.as_c_int());
        }
    }

    /// Register a callback to be called on hotplug events. The callback's
    /// [Hotplug::device_arrived] method is called when a new device is added to
    /// the bus, and [Hotplug::device_left] is called when it is removed.
    ///
    /// Devices can optionally be filtered by vendor (`vendor_id`) and device id
    /// (`product_id`).
    ///
    /// The callback will remain registered until the returned [Registration] is
    /// dropped, which can be done explicitly with [Context::unregister_callback].
    ///
    /// When handling a [Hotplug::device_arrived] event it is considered safe to call
    /// any `rusb` function that takes a [crate::Device]. It also safe to open a device and
    /// submit **asynchronous** transfers.
    /// However, most other functions that take a [DeviceHandle] are **not safe** to call.
    /// Examples of such functions are any of the synchronous API functions or
    /// the blocking functions that retrieve various USB descriptors.
    /// These functions must be used outside of the context of the [Hotplug] functions.
    #[deprecated(since = "0.9.0", note = "Use HotplugBuilder")]
    fn register_callback(
        &self,
        vendor_id: Option<u16>,
        product_id: Option<u16>,
        class: Option<u8>,
        callback: Box<dyn Hotplug<Self>>,
    ) -> crate::Result<Registration<Self>> {
        let mut builder = HotplugBuilder::new();

        let mut builder = &mut builder;
        if let Some(vendor_id) = vendor_id {
            builder = builder.vendor_id(vendor_id)
        }
        if let Some(product_id) = product_id {
            builder = builder.product_id(product_id)
        }
        if let Some(class) = class {
            builder = builder.class(class)
        }

        builder.register(self, callback)
    }

    /// Unregisters the callback corresponding to the given registration. The
    /// same thing can be achieved by dropping the registration.
    fn unregister_callback(&self, _reg: Registration<Self>) {}

    /// Handle any pending events.
    /// If timeout less then 1 microseconds then this function will handle any already-pending
    /// events and then immediately return in non-blocking style.
    /// If timeout is [None] then function will handle any pending events in blocking mode.
    fn handle_events(&self, timeout: Option<Duration>) -> crate::Result<()> {
        let n = unsafe {
            match timeout {
                Some(t) => {
                    let tv = timeval {
                        tv_sec: t.as_secs() as Seconds,
                        tv_usec: t.subsec_nanos() as MicroSeconds / 1000,
                    };
                    libusb_handle_events_timeout_completed(self.as_raw(), &tv, ptr::null_mut())
                }
                None => libusb_handle_events_completed(self.as_raw(), ptr::null_mut()),
            }
        };
        if n < 0 {
            Err(error::from_libusb(n as c_int))
        } else {
            Ok(())
        }
    }

    /// Interrupt any active thread that is handling events (for example with
    /// [handle_events][`Self::handle_events()`]).
    #[doc(alias = "libusb_interrupt_event_handler")]
    fn interrupt_handle_events(&self) {
        unsafe { libusb_interrupt_event_handler(self.as_raw()) }
    }

    fn next_timeout(&self) -> crate::Result<Option<Duration>> {
        let mut tv = timeval {
            tv_sec: 0,
            tv_usec: 0,
        };
        let n = unsafe { libusb_get_next_timeout(self.as_raw(), &mut tv) };

        match n.cmp(&0) {
            Ordering::Less => Err(error::from_libusb(n as c_int)),
            Ordering::Equal => Ok(None),
            Ordering::Greater => {
                let duration = Duration::new(tv.tv_sec as _, (tv.tv_usec * 1000) as _);
                Ok(Some(duration))
            }
        }
    }
}

impl UsbContext for Context {
    fn as_raw(&self) -> *mut libusb_context {
        self.context.inner.as_ptr()
    }
}

impl UsbContext for GlobalContext {
    fn as_raw(&self) -> *mut libusb_context {
        static mut USB_CONTEXT: *mut libusb_context = ptr::null_mut();
        static ONCE: Once = Once::new();

        ONCE.call_once(|| {
            let mut context = mem::MaybeUninit::<*mut libusb_context>::uninit();
            unsafe {
                USB_CONTEXT = match libusb_init(context.as_mut_ptr()) {
                    0 => context.assume_init(),
                    err => panic!(
                        "Can't init Global usb context, error {:?}",
                        error::from_libusb(err)
                    ),
                }
            };
        });
        // Clone data that is safe to use concurrently.
        unsafe { USB_CONTEXT }
    }
}

impl Context {
    /// Opens a new `libusb` context.
    pub fn new() -> crate::Result<Self> {
        let mut context = mem::MaybeUninit::<*mut libusb_context>::uninit();

        try_unsafe!(libusb_init(context.as_mut_ptr()));

        Ok(unsafe { Self::from_raw(context.assume_init()) })
    }

    /// Creates a new `libusb` context and sets runtime options.
    pub fn with_options(opts: &[crate::UsbOption]) -> crate::Result<Self> {
        let mut this = Self::new()?;

        for opt in opts {
            opt.apply(&mut this)?;
        }

        Ok(this)
    }

    /// Creates rusb Context from existing libusb context.
    /// Note: This transfers ownership of the context to Rust.
    /// # Safety
    /// This is unsafe because it does not check if the context is valid,
    /// so the caller must guarantee that libusb_context is created properly.
    pub unsafe fn from_raw(raw: *mut libusb_context) -> Self {
        Context {
            context: Arc::new(ContextInner {
                inner: ptr::NonNull::new_unchecked(raw),
            }),
        }
    }
}

/// Library logging levels.
#[derive(Clone, Copy)]
pub enum LogLevel {
    /// No messages are printed by `libusb` (default).
    None,

    /// Error messages printed to `stderr`.
    Error,

    /// Warning and error messages are printed to `stderr`.
    Warning,

    /// Informational messages are printed to `stdout`. Warnings and error messages are printed to
    /// `stderr`.
    Info,

    /// Debug and informational messages are printed to `stdout`. Warnings and error messages are
    /// printed to `stderr`.
    Debug,
}

impl LogLevel {
    pub(crate) fn as_c_int(self) -> c_int {
        match self {
            LogLevel::None => LIBUSB_LOG_LEVEL_NONE,
            LogLevel::Error => LIBUSB_LOG_LEVEL_ERROR,
            LogLevel::Warning => LIBUSB_LOG_LEVEL_WARNING,
            LogLevel::Info => LIBUSB_LOG_LEVEL_INFO,
            LogLevel::Debug => LIBUSB_LOG_LEVEL_DEBUG,
        }
    }

    fn from_c_int(value: c_int) -> LogLevel {
        match value {
            LIBUSB_LOG_LEVEL_ERROR => LogLevel::Error,
            LIBUSB_LOG_LEVEL_WARNING => LogLevel::Warning,
            LIBUSB_LOG_LEVEL_INFO => LogLevel::Info,
            LIBUSB_LOG_LEVEL_DEBUG => LogLevel::Debug,
            _ => LogLevel::None,
        }
    }
}

pub enum LogCallbackMode {
    /// Callback function handling all log messages.
    Global,

    /// Callback function handling context related log messages.
    Context,
}

impl LogCallbackMode {
    fn as_c_int(&self) -> c_int {
        match *self {
            LogCallbackMode::Global => LIBUSB_LOG_CB_GLOBAL,
            LogCallbackMode::Context => LIBUSB_LOG_CB_CONTEXT,
        }
    }
}
