// This is a part of Chrono.
// See README.md and LICENSE.txt for details.

//! ISO 8601 week.

use std::fmt;

use super::internals::{DateImpl, Of, YearFlags};

/// ISO 8601 week.
///
/// This type, combined with [`Weekday`](../enum.Weekday.html),
/// constitues the ISO 8601 [week date](./struct.NaiveDate.html#week-date).
/// One can retrieve this type from the existing [`Datelike`](../trait.Datelike.html) types
/// via the [`Datelike::iso_week`](../trait.Datelike.html#tymethod.iso_week) method.
#[derive(PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]
pub struct IsoWeek {
    // note that this allows for larger year range than `NaiveDate`.
    // this is crucial because we have an edge case for the first and last week supported,
    // which year number might not match the calendar year number.
    ywf: DateImpl, // (year << 10) | (week << 4) | flag
}

/// Returns the corresponding `IsoWeek` from the year and the `Of` internal value.
//
// internal use only. we don't expose the public constructor for `IsoWeek` for now,
// because the year range for the week date and the calendar date do not match and
// it is confusing to have a date that is out of range in one and not in another.
// currently we sidestep this issue by making `IsoWeek` fully dependent of `Datelike`.
pub fn iso_week_from_yof(year: i32, of: Of) -> IsoWeek {
    let (rawweek, _) = of.isoweekdate_raw();
    let (year, week) = if rawweek < 1 { // previous year
        let prevlastweek = YearFlags::from_year(year - 1).nisoweeks();
        (year - 1, prevlastweek)
    } else {
        let lastweek = of.flags().nisoweeks();
        if rawweek > lastweek { // next year
            (year + 1, 1)
        } else {
            (year, rawweek)
        }
    };
    IsoWeek { ywf: (year << 10) | (week << 4) as DateImpl | DateImpl::from(of.flags().0) }
}

impl IsoWeek {
    /// Returns the year number for this ISO week.
    ///
    /// # Example
    ///
    /// ~~~~
    /// use chrono::{NaiveDate, Datelike, Weekday};
    ///
    /// let d = NaiveDate::from_isoywd(2015, 1, Weekday::Mon);
    /// assert_eq!(d.iso_week().year(), 2015);
    /// ~~~~
    ///
    /// This year number might not match the calendar year number.
    /// Continuing the example...
    ///
    /// ~~~~
    /// # use chrono::{NaiveDate, Datelike, Weekday};
    /// # let d = NaiveDate::from_isoywd(2015, 1, Weekday::Mon);
    /// assert_eq!(d.year(), 2014);
    /// assert_eq!(d, NaiveDate::from_ymd(2014, 12, 29));
    /// ~~~~
    #[inline]
    pub fn year(&self) -> i32 {
        self.ywf >> 10
    }

    /// Returns the ISO week number starting from 1.
    ///
    /// The return value ranges from 1 to 53. (The last week of year differs by years.)
    ///
    /// # Example
    ///
    /// ~~~~
    /// use chrono::{NaiveDate, Datelike, Weekday};
    ///
    /// let d = NaiveDate::from_isoywd(2015, 15, Weekday::Mon);
    /// assert_eq!(d.iso_week().week(), 15);
    /// ~~~~
    #[inline]
    pub fn week(&self) -> u32 {
        ((self.ywf >> 4) & 0x3f) as u32
    }

    /// Returns the ISO week number starting from 0.
    ///
    /// The return value ranges from 0 to 52. (The last week of year differs by years.)
    ///
    /// # Example
    ///
    /// ~~~~
    /// use chrono::{NaiveDate, Datelike, Weekday};
    ///
    /// let d = NaiveDate::from_isoywd(2015, 15, Weekday::Mon);
    /// assert_eq!(d.iso_week().week0(), 14);
    /// ~~~~
    #[inline]
    pub fn week0(&self) -> u32 {
        ((self.ywf >> 4) & 0x3f) as u32 - 1
    }
}

/// The `Debug` output of the ISO week `w` is same to
/// [`d.format("%G-W%V")`](../format/strftime/index.html)
/// where `d` is any `NaiveDate` value in that week.
///
/// # Example
///
/// ~~~~
/// use chrono::{NaiveDate, Datelike};
///
/// assert_eq!(format!("{:?}", NaiveDate::from_ymd(2015,  9,  5).iso_week()), "2015-W36");
/// assert_eq!(format!("{:?}", NaiveDate::from_ymd(   0,  1,  3).iso_week()), "0000-W01");
/// assert_eq!(format!("{:?}", NaiveDate::from_ymd(9999, 12, 31).iso_week()), "9999-W52");
/// ~~~~
///
/// ISO 8601 requires an explicit sign for years before 1 BCE or after 9999 CE.
///
/// ~~~~
/// # use chrono::{NaiveDate, Datelike};
/// assert_eq!(format!("{:?}", NaiveDate::from_ymd(    0,  1,  2).iso_week()),  "-0001-W52");
/// assert_eq!(format!("{:?}", NaiveDate::from_ymd(10000, 12, 31).iso_week()), "+10000-W52");
/// ~~~~
impl fmt::Debug for IsoWeek {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let year = self.year();
        let week = self.week();
        if 0 <= year && year <= 9999 {
            write!(f, "{:04}-W{:02}", year, week)
        } else {
            // ISO 8601 requires the explicit sign for out-of-range years
            write!(f, "{:+05}-W{:02}", year, week)
        }
    }
}

#[cfg(test)]
mod tests {
    use naive::{internals, MIN_DATE, MAX_DATE};
    use Datelike;

    #[test]
    fn test_iso_week_extremes() {
        let minweek = MIN_DATE.iso_week();
        let maxweek = MAX_DATE.iso_week();

        assert_eq!(minweek.year(), internals::MIN_YEAR);
        assert_eq!(minweek.week(), 1);
        assert_eq!(minweek.week0(), 0);
        assert_eq!(format!("{:?}", minweek), MIN_DATE.format("%G-W%V").to_string());

        assert_eq!(maxweek.year(), internals::MAX_YEAR + 1);
        assert_eq!(maxweek.week(), 1);
        assert_eq!(maxweek.week0(), 0);
        assert_eq!(format!("{:?}", maxweek), MAX_DATE.format("%G-W%V").to_string());
    }
}
