// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std;
use std::fmt;
use std::marker::PhantomData;
use std::mem;
use std::mem::ManuallyDrop;
use std::ops::{Deref, DerefMut};
use std::os::raw::c_void;

pub use core_foundation_sys::base::*;

use string::CFString;
use ConcreteCFType;

pub trait CFIndexConvertible {
    /// Always use this method to construct a `CFIndex` value. It performs bounds checking to
    /// ensure the value is in range.
    fn to_CFIndex(self) -> CFIndex;
}

impl CFIndexConvertible for usize {
    #[inline]
    fn to_CFIndex(self) -> CFIndex {
        let max_CFIndex = CFIndex::max_value();
        if self > (max_CFIndex as usize) {
            panic!("value out of range")
        }
        self as CFIndex
    }
}

declare_TCFType!{
    /// Superclass of all Core Foundation objects.
    CFType, CFTypeRef
}

impl CFType {
    /// Try to downcast the `CFType` to a subclass. Checking if the instance is the
    /// correct subclass happens at runtime and `None` is returned if it is not the correct type.
    /// Works similar to [`Box::downcast`] and [`CFPropertyList::downcast`].
    ///
    /// # Examples
    ///
    /// ```
    /// # use core_foundation::string::CFString;
    /// # use core_foundation::boolean::CFBoolean;
    /// # use core_foundation::base::{CFType, TCFType};
    /// #
    /// // Create a string.
    /// let string: CFString = CFString::from_static_string("FooBar");
    /// // Cast it up to a CFType.
    /// let cf_type: CFType = string.as_CFType();
    /// // Cast it down again.
    /// assert!(cf_type.downcast::<CFString>().unwrap().to_string() == "FooBar");
    /// // Casting it to some other type will yield `None`
    /// assert!(cf_type.downcast::<CFBoolean>().is_none());
    /// ```
    ///
    /// ```compile_fail
    /// # use core_foundation::array::CFArray;
    /// # use core_foundation::base::TCFType;
    /// # use core_foundation::boolean::CFBoolean;
    /// # use core_foundation::string::CFString;
    /// #
    /// let boolean_array = CFArray::from_CFTypes(&[CFBoolean::true_value()]).into_CFType();
    ///
    /// // This downcast is not allowed and causes compiler error, since it would cause undefined
    /// // behavior to access the elements of the array as a CFString:
    /// let invalid_string_array = boolean_array
    ///     .downcast_into::<CFArray<CFString>>()
    ///     .unwrap();
    /// ```
    ///
    /// [`Box::downcast`]: https://doc.rust-lang.org/std/boxed/struct.Box.html#method.downcast
    /// [`CFPropertyList::downcast`]: ../propertylist/struct.CFPropertyList.html#method.downcast
    #[inline]
    pub fn downcast<T: ConcreteCFType>(&self) -> Option<T> {
        if self.instance_of::<T>() {
            unsafe {
                let reference = T::Ref::from_void_ptr(self.0);
                Some(T::wrap_under_get_rule(reference))
            }
        } else {
            None
        }
    }

    /// Similar to [`downcast`], but consumes self and can thus avoid touching the retain count.
    ///
    /// [`downcast`]: #method.downcast
    #[inline]
    pub fn downcast_into<T: ConcreteCFType>(self) -> Option<T> {
        if self.instance_of::<T>() {
            unsafe {
                let reference = T::Ref::from_void_ptr(self.0);
                mem::forget(self);
                Some(T::wrap_under_create_rule(reference))
            }
        } else {
            None
        }
    }
}

impl fmt::Debug for CFType {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let desc = unsafe {
            CFString::wrap_under_create_rule(CFCopyDescription(self.0))
        };
        desc.fmt(f)
    }
}

impl Clone for CFType {
    #[inline]
    fn clone(&self) -> CFType {
        unsafe {
            TCFType::wrap_under_get_rule(self.0)
        }
    }
}

impl PartialEq for CFType {
    #[inline]
    fn eq(&self, other: &CFType) -> bool {
        unsafe {
            CFEqual(self.as_CFTypeRef(), other.as_CFTypeRef()) != 0
        }
    }
}

declare_TCFType!(CFAllocator, CFAllocatorRef);
impl_TCFType!(CFAllocator, CFAllocatorRef, CFAllocatorGetTypeID);

impl CFAllocator {
    #[inline]
    pub fn new(mut context: CFAllocatorContext) -> CFAllocator {
        unsafe {
            let allocator_ref = CFAllocatorCreate(kCFAllocatorDefault, &mut context);
            TCFType::wrap_under_create_rule(allocator_ref)
        }
    }
}


/// All Core Foundation types implement this trait. The associated type `Ref` specifies the
/// associated Core Foundation type: e.g. for `CFType` this is `CFTypeRef`; for `CFArray` this is
/// `CFArrayRef`.
pub trait TCFType {
    /// The reference type wrapped inside this type.
    type Ref: TCFTypeRef;

    /// Returns the object as its concrete TypeRef.
    fn as_concrete_TypeRef(&self) -> Self::Ref;

    /// Returns an instance of the object, wrapping the underlying `CFTypeRef` subclass. Use this
    /// when following Core Foundation's "Create Rule". The reference count is *not* bumped.
    unsafe fn wrap_under_create_rule(obj: Self::Ref) -> Self;

    /// Returns the type ID for this class.
    fn type_id() -> CFTypeID;

    /// Returns the object as a wrapped `CFType`. The reference count is incremented by one.
    #[inline]
    fn as_CFType(&self) -> CFType {
        unsafe {
            TCFType::wrap_under_get_rule(self.as_CFTypeRef())
        }
    }

    /// Returns the object as a wrapped `CFType`. Consumes self and avoids changing the reference
    /// count.
    #[inline]
    fn into_CFType(self) -> CFType
    where
        Self: Sized,
    {
        let reference = self.as_CFTypeRef();
        mem::forget(self);
        unsafe { TCFType::wrap_under_create_rule(reference) }
    }

    /// Returns the object as a raw `CFTypeRef`. The reference count is not adjusted.
    fn as_CFTypeRef(&self) -> CFTypeRef;

    /// Returns an instance of the object, wrapping the underlying `CFTypeRef` subclass. Use this
    /// when following Core Foundation's "Get Rule". The reference count *is* bumped.
    unsafe fn wrap_under_get_rule(reference: Self::Ref) -> Self;

    /// Returns the reference count of the object. It is unwise to do anything other than test
    /// whether the return value of this method is greater than zero.
    #[inline]
    fn retain_count(&self) -> CFIndex {
        unsafe {
            CFGetRetainCount(self.as_CFTypeRef())
        }
    }

    /// Returns the type ID of this object.
    #[inline]
    fn type_of(&self) -> CFTypeID {
        unsafe {
            CFGetTypeID(self.as_CFTypeRef())
        }
    }

    /// Writes a debugging version of this object on standard error.
    fn show(&self) {
        unsafe {
            CFShow(self.as_CFTypeRef())
        }
    }

    /// Returns true if this value is an instance of another type.
    #[inline]
    fn instance_of<OtherCFType: TCFType>(&self) -> bool {
        self.type_of() == OtherCFType::type_id()
    }
}

impl TCFType for CFType {
    type Ref = CFTypeRef;

    #[inline]
    fn as_concrete_TypeRef(&self) -> CFTypeRef {
        self.0
    }

    #[inline]
    unsafe fn wrap_under_get_rule(reference: CFTypeRef) -> CFType {
        let reference: CFTypeRef = CFRetain(reference);
        TCFType::wrap_under_create_rule(reference)
    }

    #[inline]
    fn as_CFTypeRef(&self) -> CFTypeRef {
        self.as_concrete_TypeRef()
    }

    #[inline]
    unsafe fn wrap_under_create_rule(obj: CFTypeRef) -> CFType {
        CFType(obj)
    }

    #[inline]
    fn type_id() -> CFTypeID {
        // FIXME(pcwalton): Is this right?
        0
    }
}

/// A reference to an element inside a container
pub struct ItemRef<'a, T: 'a>(ManuallyDrop<T>, PhantomData<&'a T>);

impl<'a, T> Deref for ItemRef<'a, T> {
    type Target = T;

    fn deref(&self) -> &T {
        &self.0
    }
}

impl<'a, T: fmt::Debug> fmt::Debug for ItemRef<'a, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        self.0.fmt(f)
    }
}

impl<'a, T: PartialEq> PartialEq for ItemRef<'a, T> {
    fn eq(&self, other: &Self) -> bool {
        self.0.eq(&other.0)
    }
}

/// A reference to a mutable element inside a container
pub struct ItemMutRef<'a, T: 'a>(ManuallyDrop<T>, PhantomData<&'a T>);

impl<'a, T> Deref for ItemMutRef<'a, T> {
    type Target = T;

    fn deref(&self) -> &T {
        &self.0
    }
}

impl<'a, T> DerefMut for ItemMutRef<'a, T> {
    fn deref_mut(&mut self) -> &mut T {
        &mut self.0
    }
}

impl<'a, T: fmt::Debug> fmt::Debug for ItemMutRef<'a, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        self.0.fmt(f)
    }
}

impl<'a, T: PartialEq> PartialEq for ItemMutRef<'a, T> {
    fn eq(&self, other: &Self) -> bool {
        self.0.eq(&other.0)
    }
}

/// A trait describing how to convert from the stored *mut c_void to the desired T
pub unsafe trait FromMutVoid {
    unsafe fn from_mut_void<'a>(x: *mut c_void) -> ItemMutRef<'a, Self> where Self: std::marker::Sized;
}

unsafe impl FromMutVoid for u32 {
    unsafe fn from_mut_void<'a>(x: *mut c_void) -> ItemMutRef<'a, Self> {
        ItemMutRef(ManuallyDrop::new(x as u32), PhantomData)
    }
}

unsafe impl FromMutVoid for *const c_void {
    unsafe fn from_mut_void<'a>(x: *mut c_void) -> ItemMutRef<'a, Self> {
        ItemMutRef(ManuallyDrop::new(x), PhantomData)
    }
}

unsafe impl<T: TCFType> FromMutVoid for T {
    unsafe fn from_mut_void<'a>(x: *mut c_void) -> ItemMutRef<'a, Self> {
        ItemMutRef(ManuallyDrop::new(TCFType::wrap_under_create_rule(T::Ref::from_void_ptr(x))), PhantomData)
    }
}

/// A trait describing how to convert from the stored *const c_void to the desired T
pub unsafe trait FromVoid {
    unsafe fn from_void<'a>(x: *const c_void) -> ItemRef<'a, Self> where Self: std::marker::Sized;
}

unsafe impl FromVoid for u32 {
    unsafe fn from_void<'a>(x: *const c_void) -> ItemRef<'a, Self> {
        // Functions like CGFontCopyTableTags treat the void*'s as u32's
        // so we convert by casting directly
        ItemRef(ManuallyDrop::new(x as u32), PhantomData)
    }
}

unsafe impl FromVoid for *const c_void {
    unsafe fn from_void<'a>(x: *const c_void) -> ItemRef<'a, Self> {
        ItemRef(ManuallyDrop::new(x), PhantomData)
    }
}

unsafe impl<T: TCFType> FromVoid for T {
    unsafe fn from_void<'a>(x: *const c_void) -> ItemRef<'a, Self> {
        ItemRef(ManuallyDrop::new(TCFType::wrap_under_create_rule(T::Ref::from_void_ptr(x))), PhantomData)
    }
}

/// A trait describing how to convert from the stored *const c_void to the desired T
pub unsafe trait ToVoid<T> {
    fn to_void(&self) -> *const c_void;
}

unsafe impl ToVoid<*const c_void> for *const c_void {
    fn to_void(&self) -> *const c_void {
        *self
    }
}

unsafe impl<'a> ToVoid<CFType> for &'a CFType {
    fn to_void(&self) -> *const ::std::os::raw::c_void {
        self.as_concrete_TypeRef().as_void_ptr()
    }
}

unsafe impl ToVoid<CFType> for CFType {
    fn to_void(&self) -> *const ::std::os::raw::c_void {
        self.as_concrete_TypeRef().as_void_ptr()
    }
}

unsafe impl ToVoid<CFType> for CFTypeRef {
    fn to_void(&self) -> *const ::std::os::raw::c_void {
        self.as_void_ptr()
    }
}


#[cfg(test)]
mod tests {
    use super::*;
    use std::mem;
    use boolean::CFBoolean;

    #[test]
    fn cftype_instance_of() {
        let string = CFString::from_static_string("foo");
        let cftype = string.as_CFType();

        assert!(cftype.instance_of::<CFString>());
        assert!(!cftype.instance_of::<CFBoolean>());
    }

    #[test]
    fn as_cftype_retain_count() {
        let string = CFString::from_static_string("bar");
        assert_eq!(string.retain_count(), 1);
        let cftype = string.as_CFType();
        assert_eq!(cftype.retain_count(), 2);
        mem::drop(string);
        assert_eq!(cftype.retain_count(), 1);
    }

    #[test]
    fn into_cftype_retain_count() {
        let string = CFString::from_static_string("bar");
        assert_eq!(string.retain_count(), 1);
        let cftype = string.into_CFType();
        assert_eq!(cftype.retain_count(), 1);
    }

    #[test]
    fn as_cftype_and_downcast() {
        let string = CFString::from_static_string("bar");
        let cftype = string.as_CFType();
        let string2 = cftype.downcast::<CFString>().unwrap();
        assert_eq!(string2.to_string(), "bar");

        assert_eq!(string.retain_count(), 3);
        assert_eq!(cftype.retain_count(), 3);
        assert_eq!(string2.retain_count(), 3);
    }

    #[test]
    fn into_cftype_and_downcast_into() {
        let string = CFString::from_static_string("bar");
        let cftype = string.into_CFType();
        let string2 = cftype.downcast_into::<CFString>().unwrap();
        assert_eq!(string2.to_string(), "bar");
        assert_eq!(string2.retain_count(), 1);
    }
}
