// 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.

//! Core Foundation date objects.

pub use core_foundation_sys::date::*;
use core_foundation_sys::base::kCFAllocatorDefault;

use base::TCFType;

#[cfg(feature = "with-chrono")]
use chrono::NaiveDateTime;


declare_TCFType!{
    /// A date.
    CFDate, CFDateRef
}
impl_TCFType!(CFDate, CFDateRef, CFDateGetTypeID);
impl_CFTypeDescription!(CFDate);
impl_CFComparison!(CFDate, CFDateCompare);

impl CFDate {
    #[inline]
    pub fn new(time: CFAbsoluteTime) -> CFDate {
        unsafe {
            let date_ref = CFDateCreate(kCFAllocatorDefault, time);
            TCFType::wrap_under_create_rule(date_ref)
        }
    }

    #[inline]
    pub fn now() -> CFDate {
        CFDate::new(unsafe { CFAbsoluteTimeGetCurrent() })
    }

    #[inline]
    pub fn abs_time(&self) -> CFAbsoluteTime {
        unsafe {
            CFDateGetAbsoluteTime(self.0)
        }
    }

    #[cfg(feature = "with-chrono")]
    pub fn naive_utc(&self) -> NaiveDateTime {
        let ts = unsafe {
            self.abs_time() + kCFAbsoluteTimeIntervalSince1970
        };
        let (secs, nanos) = if ts.is_sign_positive() {
            (ts.trunc() as i64, ts.fract())
        } else {
            // nanoseconds can't be negative in NaiveDateTime
            (ts.trunc() as i64 - 1, 1.0 - ts.fract().abs())
        };
        NaiveDateTime::from_timestamp(secs, (nanos * 1e9).floor() as u32)
    }

    #[cfg(feature = "with-chrono")]
    pub fn from_naive_utc(time: NaiveDateTime) -> CFDate {
        let secs = time.timestamp();
        let nanos = time.timestamp_subsec_nanos();
        let ts = unsafe {
            secs as f64 + (nanos as f64 / 1e9) - kCFAbsoluteTimeIntervalSince1970
        };
        CFDate::new(ts)
    }
}

#[cfg(test)]
mod test {
    use super::CFDate;
    use std::cmp::Ordering;

    #[cfg(feature = "with-chrono")]
    use chrono::NaiveDateTime;

    #[cfg(feature = "with-chrono")]
    fn approx_eq(a: f64, b: f64) -> bool {
        use std::f64;

        let same_sign = a.is_sign_positive() == b.is_sign_positive();
        let equal = ((a - b).abs() / f64::min(a.abs() + b.abs(), f64::MAX)) < f64::EPSILON;
        (same_sign && equal)
    }

    #[test]
    fn date_comparison() {
        let now = CFDate::now();
        let past = CFDate::new(now.abs_time() - 1.0);
        assert_eq!(now.cmp(&past), Ordering::Greater);
        assert_eq!(now.cmp(&now), Ordering::Equal);
        assert_eq!(past.cmp(&now), Ordering::Less);
    }

    #[test]
    fn date_equality() {
        let now = CFDate::now();
        let same_time = CFDate::new(now.abs_time());
        assert_eq!(now, same_time);
    }

    #[test]
    #[cfg(feature = "with-chrono")]
    fn date_chrono_conversion_positive() {
        let date = CFDate::now();
        let datetime = date.naive_utc();
        let converted = CFDate::from_naive_utc(datetime);
        assert!(approx_eq(date.abs_time(), converted.abs_time()));
    }

    #[test]
    #[cfg(feature = "with-chrono")]
    fn date_chrono_conversion_negative() {
        use super::kCFAbsoluteTimeIntervalSince1970;

        let ts = unsafe {
            kCFAbsoluteTimeIntervalSince1970 - 420.0
        };
        let date = CFDate::new(ts);
        let datetime: NaiveDateTime = date.naive_utc();
        let converted = CFDate::from_naive_utc(datetime);
        assert!(approx_eq(date.abs_time(), converted.abs_time()));
    }
}
