//! The Warning infrastructure for the OCPI `DayOfWeek` type.
//!
//! We rename the type of `Weekday` as this is the common way of expressing the concept in English.
//!
//! * See: [OCPI spec 2.2.1: Tariff DayOfWeek](<https://github.com/ocpi/ocpi/blob/release-2.2.1-bugfixes/mod_tariffs.asciidoc#mod_tariffs_dayofweek_enum>)
//! * See: [OCPI spec 2.1.1: Tariff DayOfWeek](<https://github.com/ocpi/ocpi/blob/release-2.1.1-bugfixes/mod_tariffs.md#41-dayofweek-enum>)

#[cfg(test)]
mod test_day_of_week;

use crate::{define_enum_from_json, Enum, IntoEnum};

/// A single day of the week.
#[derive(Copy, Debug, PartialEq, Eq, Ord, PartialOrd, Clone, Hash)]
pub(crate) enum Weekday {
    /// Monday.
    Monday,
    /// Tuesday.
    Tuesday,
    /// Wednesday.
    Wednesday,
    /// Thursday.
    Thursday,
    /// Friday.
    Friday,
    /// Saturday.
    Saturday,
    /// Sunday.
    Sunday,
}

impl IntoEnum for Weekday {
    fn enum_from_str(s: &str) -> Enum<Self> {
        let dt = if s.eq_ignore_ascii_case("monday") {
            Self::Monday
        } else if s.eq_ignore_ascii_case("tuesday") {
            Self::Tuesday
        } else if s.eq_ignore_ascii_case("wednesday") {
            Self::Wednesday
        } else if s.eq_ignore_ascii_case("thursday") {
            Self::Thursday
        } else if s.eq_ignore_ascii_case("friday") {
            Self::Friday
        } else if s.eq_ignore_ascii_case("saturday") {
            Self::Saturday
        } else if s.eq_ignore_ascii_case("sunday") {
            Self::Sunday
        } else {
            return Enum::Unknown(s.to_owned());
        };

        Enum::Known(dt)
    }
}

define_enum_from_json!(Weekday, display_name: "weekday", warning_id: "weekday");

/// Convert a `chrono::Weekday` into an OCPI `Weekday`.
impl From<chrono::Weekday> for Weekday {
    fn from(value: chrono::Weekday) -> Self {
        match value {
            chrono::Weekday::Mon => Weekday::Monday,
            chrono::Weekday::Tue => Weekday::Tuesday,
            chrono::Weekday::Wed => Weekday::Wednesday,
            chrono::Weekday::Thu => Weekday::Thursday,
            chrono::Weekday::Fri => Weekday::Friday,
            chrono::Weekday::Sat => Weekday::Saturday,
            chrono::Weekday::Sun => Weekday::Sunday,
        }
    }
}

/// Convert a `Weekday` into an index.
impl From<Weekday> for usize {
    fn from(value: Weekday) -> Self {
        match value {
            Weekday::Monday => 0,
            Weekday::Tuesday => 1,
            Weekday::Wednesday => 2,
            Weekday::Thursday => 3,
            Weekday::Friday => 4,
            Weekday::Saturday => 5,
            Weekday::Sunday => 6,
        }
    }
}

impl From<Weekday> for chrono::Weekday {
    fn from(day: Weekday) -> Self {
        match day {
            Weekday::Monday => Self::Mon,
            Weekday::Tuesday => Self::Tue,
            Weekday::Wednesday => Self::Wed,
            Weekday::Thursday => Self::Thu,
            Weekday::Friday => Self::Fri,
            Weekday::Saturday => Self::Sat,
            Weekday::Sunday => Self::Sun,
        }
    }
}
