use self::sync_bitset::*;
use crate::cell::Cell;
use crate::mem;
use crate::num::NonZeroUsize;
use crate::ptr;
use crate::sync::atomic::{AtomicUsize, Ordering};

#[cfg(target_pointer_width = "64")]
const USIZE_BITS: usize = 64;
const TLS_KEYS: usize = 128; // Same as POSIX minimum
const TLS_KEYS_BITSET_SIZE: usize = (TLS_KEYS + (USIZE_BITS - 1)) / USIZE_BITS;

#[cfg_attr(test, linkage = "available_externally")]
#[export_name = "_ZN16__rust_internals3std3sys3sgx3abi3tls14TLS_KEY_IN_USEE"]
static TLS_KEY_IN_USE: SyncBitset = SYNC_BITSET_INIT;
macro_rules! dup {
    ((* $($exp:tt)*) $($val:tt)*) => (dup!( ($($exp)*) $($val)* $($val)* ));
    (() $($val:tt)*) => ([$($val),*])
}
#[cfg_attr(test, linkage = "available_externally")]
#[export_name = "_ZN16__rust_internals3std3sys3sgx3abi3tls14TLS_DESTRUCTORE"]
static TLS_DESTRUCTOR: [AtomicUsize; TLS_KEYS] = dup!((* * * * * * *) (AtomicUsize::new(0)));

extern "C" {
    fn get_tls_ptr() -> *const u8;
    fn set_tls_ptr(tls: *const u8);
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct Key(NonZeroUsize);

impl Key {
    fn to_index(self) -> usize {
        self.0.get() - 1
    }

    fn from_index(index: usize) -> Self {
        Key(NonZeroUsize::new(index + 1).unwrap())
    }

    pub fn as_usize(self) -> usize {
        self.0.get()
    }

    pub fn from_usize(index: usize) -> Self {
        Key(NonZeroUsize::new(index).unwrap())
    }
}

#[repr(C)]
pub struct Tls {
    data: [Cell<*mut u8>; TLS_KEYS],
}

pub struct ActiveTls<'a> {
    tls: &'a Tls,
}

impl<'a> Drop for ActiveTls<'a> {
    fn drop(&mut self) {
        let value_with_destructor = |key: usize| {
            let ptr = TLS_DESTRUCTOR[key].load(Ordering::Relaxed);
            unsafe { mem::transmute::<_, Option<unsafe extern "C" fn(*mut u8)>>(ptr) }
                .map(|dtor| (&self.tls.data[key], dtor))
        };

        let mut any_non_null_dtor = true;
        while any_non_null_dtor {
            any_non_null_dtor = false;
            for (value, dtor) in TLS_KEY_IN_USE.iter().filter_map(&value_with_destructor) {
                let value = value.replace(ptr::null_mut());
                if value != ptr::null_mut() {
                    any_non_null_dtor = true;
                    unsafe { dtor(value) }
                }
            }
        }
    }
}

impl Tls {
    pub fn new() -> Tls {
        Tls { data: dup!((* * * * * * *) (Cell::new(ptr::null_mut()))) }
    }

    pub unsafe fn activate(&self) -> ActiveTls<'_> {
        set_tls_ptr(self as *const Tls as _);
        ActiveTls { tls: self }
    }

    #[allow(unused)]
    pub unsafe fn activate_persistent(self: Box<Self>) {
        set_tls_ptr((&*self) as *const Tls as _);
        mem::forget(self);
    }

    unsafe fn current<'a>() -> &'a Tls {
        &*(get_tls_ptr() as *const Tls)
    }

    pub fn create(dtor: Option<unsafe extern "C" fn(*mut u8)>) -> Key {
        let index = if let Some(index) = TLS_KEY_IN_USE.set() {
            index
        } else {
            rtabort!("TLS limit exceeded")
        };
        TLS_DESTRUCTOR[index].store(dtor.map_or(0, |f| f as usize), Ordering::Relaxed);
        Key::from_index(index)
    }

    pub fn set(key: Key, value: *mut u8) {
        let index = key.to_index();
        rtassert!(TLS_KEY_IN_USE.get(index));
        unsafe { Self::current() }.data[index].set(value);
    }

    pub fn get(key: Key) -> *mut u8 {
        let index = key.to_index();
        rtassert!(TLS_KEY_IN_USE.get(index));
        unsafe { Self::current() }.data[index].get()
    }

    pub fn destroy(key: Key) {
        TLS_KEY_IN_USE.clear(key.to_index());
    }
}

mod sync_bitset {
    use super::{TLS_KEYS_BITSET_SIZE, USIZE_BITS};
    use crate::iter::{Enumerate, Peekable};
    use crate::slice::Iter;
    use crate::sync::atomic::{AtomicUsize, Ordering};

    /// A bitset that can be used synchronously.
    pub(super) struct SyncBitset([AtomicUsize; TLS_KEYS_BITSET_SIZE]);

    pub(super) const SYNC_BITSET_INIT: SyncBitset =
        SyncBitset([AtomicUsize::new(0), AtomicUsize::new(0)]);

    impl SyncBitset {
        pub fn get(&self, index: usize) -> bool {
            let (hi, lo) = Self::split(index);
            (self.0[hi].load(Ordering::Relaxed) & lo) != 0
        }

        /// Not atomic.
        pub fn iter(&self) -> SyncBitsetIter<'_> {
            SyncBitsetIter { iter: self.0.iter().enumerate().peekable(), elem_idx: 0 }
        }

        pub fn clear(&self, index: usize) {
            let (hi, lo) = Self::split(index);
            self.0[hi].fetch_and(!lo, Ordering::Relaxed);
        }

        /// Sets any unset bit. Not atomic. Returns `None` if all bits were
        /// observed to be set.
        pub fn set(&self) -> Option<usize> {
            'elems: for (idx, elem) in self.0.iter().enumerate() {
                let mut current = elem.load(Ordering::Relaxed);
                loop {
                    if 0 == !current {
                        continue 'elems;
                    }
                    let trailing_ones = (!current).trailing_zeros() as usize;
                    match elem.compare_exchange(
                        current,
                        current | (1 << trailing_ones),
                        Ordering::AcqRel,
                        Ordering::Relaxed,
                    ) {
                        Ok(_) => return Some(idx * USIZE_BITS + trailing_ones),
                        Err(previous) => current = previous,
                    }
                }
            }
            None
        }

        fn split(index: usize) -> (usize, usize) {
            (index / USIZE_BITS, 1 << (index % USIZE_BITS))
        }
    }

    pub(super) struct SyncBitsetIter<'a> {
        iter: Peekable<Enumerate<Iter<'a, AtomicUsize>>>,
        elem_idx: usize,
    }

    impl<'a> Iterator for SyncBitsetIter<'a> {
        type Item = usize;

        fn next(&mut self) -> Option<usize> {
            self.iter.peek().cloned().and_then(|(idx, elem)| {
                let elem = elem.load(Ordering::Relaxed);
                let low_mask = (1 << self.elem_idx) - 1;
                let next = elem & !low_mask;
                let next_idx = next.trailing_zeros() as usize;
                self.elem_idx = next_idx + 1;
                if self.elem_idx >= 64 {
                    self.elem_idx = 0;
                    self.iter.next();
                }
                match next_idx {
                    64 => self.next(),
                    _ => Some(idx * USIZE_BITS + next_idx),
                }
            })
        }
    }

    #[cfg(test)]
    mod tests {
        use super::*;

        fn test_data(bitset: [usize; 2], bit_indices: &[usize]) {
            let set = SyncBitset([AtomicUsize::new(bitset[0]), AtomicUsize::new(bitset[1])]);
            assert_eq!(set.iter().collect::<Vec<_>>(), bit_indices);
            for &i in bit_indices {
                assert!(set.get(i));
            }
        }

        #[test]
        fn iter() {
            test_data([0b0110_1001, 0], &[0, 3, 5, 6]);
            test_data([0x8000_0000_0000_0000, 0x8000_0000_0000_0001], &[63, 64, 127]);
            test_data([0, 0], &[]);
        }

        #[test]
        fn set_get_clear() {
            let set = SYNC_BITSET_INIT;
            let key = set.set().unwrap();
            assert!(set.get(key));
            set.clear(key);
            assert!(!set.get(key));
        }
    }
}
