// Generated by scripts/generate-holidays.py

use std::fmt::Display;
use std::str::FromStr;

use super::UnknownCountryCode;

/// An enum for selecting a country.
///
/// ```
/// use opening_hours::localization::Country;
///
/// let country: Country = "FR".parse().unwrap();
/// assert_eq!(country, Country::FR);
/// ```
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum Country {
    /// Andorra
    AD,
    /// Albania
    AL,
    /// Armenia
    AM,
    /// Argentina
    AR,
    /// Austria
    AT,
    /// Australia
    AU,
    /// Åland Islands
    AX,
    /// Bosnia and Herzegovina
    BA,
    /// Barbados
    BB,
    /// Belgium
    BE,
    /// Bulgaria
    BG,
    /// Benin
    BJ,
    /// Bolivia
    BO,
    /// Brazil
    BR,
    /// Bahamas
    BS,
    /// Botswana
    BW,
    /// Belarus
    BY,
    /// Belize
    BZ,
    /// Canada
    CA,
    /// Switzerland
    CH,
    /// Chile
    CL,
    /// China
    CN,
    /// Colombia
    CO,
    /// Costa Rica
    CR,
    /// Cuba
    CU,
    /// Cyprus
    CY,
    /// Czechia
    CZ,
    /// Germany
    DE,
    /// Denmark
    DK,
    /// Dominican Republic
    DO,
    /// Ecuador
    EC,
    /// Estonia
    EE,
    /// Egypt
    EG,
    /// Spain
    ES,
    /// Finland
    FI,
    /// Faroe Islands
    FO,
    /// France
    FR,
    /// Gabon
    GA,
    /// United Kingdom
    GB,
    /// Grenada
    GD,
    /// Georgia
    GE,
    /// Guernsey
    GG,
    /// Gibraltar
    GI,
    /// Greenland
    GL,
    /// Gambia
    GM,
    /// Greece
    GR,
    /// Guatemala
    GT,
    /// Guyana
    GY,
    /// Hong Kong
    HK,
    /// Honduras
    HN,
    /// Croatia
    HR,
    /// Haiti
    HT,
    /// Hungary
    HU,
    /// Indonesia
    ID,
    /// Ireland
    IE,
    /// Isle of Man
    IM,
    /// Iceland
    IS,
    /// Italy
    IT,
    /// Jersey
    JE,
    /// Jamaica
    JM,
    /// Japan
    JP,
    /// South Korea
    KR,
    /// Kazakhstan
    KZ,
    /// Liechtenstein
    LI,
    /// Lesotho
    LS,
    /// Lithuania
    LT,
    /// Luxembourg
    LU,
    /// Latvia
    LV,
    /// Morocco
    MA,
    /// Monaco
    MC,
    /// Moldova
    MD,
    /// Montenegro
    ME,
    /// Madagascar
    MG,
    /// North Macedonia
    MK,
    /// Mongolia
    MN,
    /// Montserrat
    MS,
    /// Malta
    MT,
    /// Mexico
    MX,
    /// Mozambique
    MZ,
    /// Namibia
    NA,
    /// Niger
    NE,
    /// Nigeria
    NG,
    /// Nicaragua
    NI,
    /// Netherlands
    NL,
    /// Norway
    NO,
    /// New Zealand
    NZ,
    /// Panama
    PA,
    /// Peru
    PE,
    /// Papua New Guinea
    PG,
    /// Philippines
    PH,
    /// Poland
    PL,
    /// Puerto Rico
    PR,
    /// Portugal
    PT,
    /// Paraguay
    PY,
    /// Romania
    RO,
    /// Serbia
    RS,
    /// Russia
    RU,
    /// Sweden
    SE,
    /// Singapore
    SG,
    /// Slovenia
    SI,
    /// Svalbard and Jan Mayen
    SJ,
    /// Slovakia
    SK,
    /// San Marino
    SM,
    /// Suriname
    SR,
    /// El Salvador
    SV,
    /// Tunisia
    TN,
    /// Turkey
    TR,
    /// Ukraine
    UA,
    /// United States
    US,
    /// Uruguay
    UY,
    /// Vatican City
    VA,
    /// Venezuela
    VE,
    /// Vietnam
    VN,
    /// South Africa
    ZA,
    /// Zimbabwe
    ZW,
}

impl Country {
    pub const ALL: [Self; 115] = [
        Self::AD,
        Self::AL,
        Self::AM,
        Self::AR,
        Self::AT,
        Self::AU,
        Self::AX,
        Self::BA,
        Self::BB,
        Self::BE,
        Self::BG,
        Self::BJ,
        Self::BO,
        Self::BR,
        Self::BS,
        Self::BW,
        Self::BY,
        Self::BZ,
        Self::CA,
        Self::CH,
        Self::CL,
        Self::CN,
        Self::CO,
        Self::CR,
        Self::CU,
        Self::CY,
        Self::CZ,
        Self::DE,
        Self::DK,
        Self::DO,
        Self::EC,
        Self::EE,
        Self::EG,
        Self::ES,
        Self::FI,
        Self::FO,
        Self::FR,
        Self::GA,
        Self::GB,
        Self::GD,
        Self::GE,
        Self::GG,
        Self::GI,
        Self::GL,
        Self::GM,
        Self::GR,
        Self::GT,
        Self::GY,
        Self::HK,
        Self::HN,
        Self::HR,
        Self::HT,
        Self::HU,
        Self::ID,
        Self::IE,
        Self::IM,
        Self::IS,
        Self::IT,
        Self::JE,
        Self::JM,
        Self::JP,
        Self::KR,
        Self::KZ,
        Self::LI,
        Self::LS,
        Self::LT,
        Self::LU,
        Self::LV,
        Self::MA,
        Self::MC,
        Self::MD,
        Self::ME,
        Self::MG,
        Self::MK,
        Self::MN,
        Self::MS,
        Self::MT,
        Self::MX,
        Self::MZ,
        Self::NA,
        Self::NE,
        Self::NG,
        Self::NI,
        Self::NL,
        Self::NO,
        Self::NZ,
        Self::PA,
        Self::PE,
        Self::PG,
        Self::PH,
        Self::PL,
        Self::PR,
        Self::PT,
        Self::PY,
        Self::RO,
        Self::RS,
        Self::RU,
        Self::SE,
        Self::SG,
        Self::SI,
        Self::SJ,
        Self::SK,
        Self::SM,
        Self::SR,
        Self::SV,
        Self::TN,
        Self::TR,
        Self::UA,
        Self::US,
        Self::UY,
        Self::VA,
        Self::VE,
        Self::VN,
        Self::ZA,
        Self::ZW,
    ];

    /// Get the country's full name.
    ///
    /// ```
    /// use opening_hours::localization::Country;
    ///
    /// assert_eq!(Country::FR.name(), "France");
    /// ```
    pub fn name(self) -> &'static str {
        match self {
            Self::AD => "Andorra",
            Self::AL => "Albania",
            Self::AM => "Armenia",
            Self::AR => "Argentina",
            Self::AT => "Austria",
            Self::AU => "Australia",
            Self::AX => "Åland Islands",
            Self::BA => "Bosnia and Herzegovina",
            Self::BB => "Barbados",
            Self::BE => "Belgium",
            Self::BG => "Bulgaria",
            Self::BJ => "Benin",
            Self::BO => "Bolivia",
            Self::BR => "Brazil",
            Self::BS => "Bahamas",
            Self::BW => "Botswana",
            Self::BY => "Belarus",
            Self::BZ => "Belize",
            Self::CA => "Canada",
            Self::CH => "Switzerland",
            Self::CL => "Chile",
            Self::CN => "China",
            Self::CO => "Colombia",
            Self::CR => "Costa Rica",
            Self::CU => "Cuba",
            Self::CY => "Cyprus",
            Self::CZ => "Czechia",
            Self::DE => "Germany",
            Self::DK => "Denmark",
            Self::DO => "Dominican Republic",
            Self::EC => "Ecuador",
            Self::EE => "Estonia",
            Self::EG => "Egypt",
            Self::ES => "Spain",
            Self::FI => "Finland",
            Self::FO => "Faroe Islands",
            Self::FR => "France",
            Self::GA => "Gabon",
            Self::GB => "United Kingdom",
            Self::GD => "Grenada",
            Self::GE => "Georgia",
            Self::GG => "Guernsey",
            Self::GI => "Gibraltar",
            Self::GL => "Greenland",
            Self::GM => "Gambia",
            Self::GR => "Greece",
            Self::GT => "Guatemala",
            Self::GY => "Guyana",
            Self::HK => "Hong Kong",
            Self::HN => "Honduras",
            Self::HR => "Croatia",
            Self::HT => "Haiti",
            Self::HU => "Hungary",
            Self::ID => "Indonesia",
            Self::IE => "Ireland",
            Self::IM => "Isle of Man",
            Self::IS => "Iceland",
            Self::IT => "Italy",
            Self::JE => "Jersey",
            Self::JM => "Jamaica",
            Self::JP => "Japan",
            Self::KR => "South Korea",
            Self::KZ => "Kazakhstan",
            Self::LI => "Liechtenstein",
            Self::LS => "Lesotho",
            Self::LT => "Lithuania",
            Self::LU => "Luxembourg",
            Self::LV => "Latvia",
            Self::MA => "Morocco",
            Self::MC => "Monaco",
            Self::MD => "Moldova",
            Self::ME => "Montenegro",
            Self::MG => "Madagascar",
            Self::MK => "North Macedonia",
            Self::MN => "Mongolia",
            Self::MS => "Montserrat",
            Self::MT => "Malta",
            Self::MX => "Mexico",
            Self::MZ => "Mozambique",
            Self::NA => "Namibia",
            Self::NE => "Niger",
            Self::NG => "Nigeria",
            Self::NI => "Nicaragua",
            Self::NL => "Netherlands",
            Self::NO => "Norway",
            Self::NZ => "New Zealand",
            Self::PA => "Panama",
            Self::PE => "Peru",
            Self::PG => "Papua New Guinea",
            Self::PH => "Philippines",
            Self::PL => "Poland",
            Self::PR => "Puerto Rico",
            Self::PT => "Portugal",
            Self::PY => "Paraguay",
            Self::RO => "Romania",
            Self::RS => "Serbia",
            Self::RU => "Russia",
            Self::SE => "Sweden",
            Self::SG => "Singapore",
            Self::SI => "Slovenia",
            Self::SJ => "Svalbard and Jan Mayen",
            Self::SK => "Slovakia",
            Self::SM => "San Marino",
            Self::SR => "Suriname",
            Self::SV => "El Salvador",
            Self::TN => "Tunisia",
            Self::TR => "Turkey",
            Self::UA => "Ukraine",
            Self::US => "United States",
            Self::UY => "Uruguay",
            Self::VA => "Vatican City",
            Self::VE => "Venezuela",
            Self::VN => "Vietnam",
            Self::ZA => "South Africa",
            Self::ZW => "Zimbabwe",
        }
    }

    /// Get the country's iso code.
    ///
    /// ```
    /// use opening_hours::localization::Country;
    ///
    /// assert_eq!(Country::FR.iso_code(), "FR");
    /// ```
    pub fn iso_code(self) -> &'static str {
        match self {
            Self::AD => "AD",
            Self::AL => "AL",
            Self::AM => "AM",
            Self::AR => "AR",
            Self::AT => "AT",
            Self::AU => "AU",
            Self::AX => "AX",
            Self::BA => "BA",
            Self::BB => "BB",
            Self::BE => "BE",
            Self::BG => "BG",
            Self::BJ => "BJ",
            Self::BO => "BO",
            Self::BR => "BR",
            Self::BS => "BS",
            Self::BW => "BW",
            Self::BY => "BY",
            Self::BZ => "BZ",
            Self::CA => "CA",
            Self::CH => "CH",
            Self::CL => "CL",
            Self::CN => "CN",
            Self::CO => "CO",
            Self::CR => "CR",
            Self::CU => "CU",
            Self::CY => "CY",
            Self::CZ => "CZ",
            Self::DE => "DE",
            Self::DK => "DK",
            Self::DO => "DO",
            Self::EC => "EC",
            Self::EE => "EE",
            Self::EG => "EG",
            Self::ES => "ES",
            Self::FI => "FI",
            Self::FO => "FO",
            Self::FR => "FR",
            Self::GA => "GA",
            Self::GB => "GB",
            Self::GD => "GD",
            Self::GE => "GE",
            Self::GG => "GG",
            Self::GI => "GI",
            Self::GL => "GL",
            Self::GM => "GM",
            Self::GR => "GR",
            Self::GT => "GT",
            Self::GY => "GY",
            Self::HK => "HK",
            Self::HN => "HN",
            Self::HR => "HR",
            Self::HT => "HT",
            Self::HU => "HU",
            Self::ID => "ID",
            Self::IE => "IE",
            Self::IM => "IM",
            Self::IS => "IS",
            Self::IT => "IT",
            Self::JE => "JE",
            Self::JM => "JM",
            Self::JP => "JP",
            Self::KR => "KR",
            Self::KZ => "KZ",
            Self::LI => "LI",
            Self::LS => "LS",
            Self::LT => "LT",
            Self::LU => "LU",
            Self::LV => "LV",
            Self::MA => "MA",
            Self::MC => "MC",
            Self::MD => "MD",
            Self::ME => "ME",
            Self::MG => "MG",
            Self::MK => "MK",
            Self::MN => "MN",
            Self::MS => "MS",
            Self::MT => "MT",
            Self::MX => "MX",
            Self::MZ => "MZ",
            Self::NA => "NA",
            Self::NE => "NE",
            Self::NG => "NG",
            Self::NI => "NI",
            Self::NL => "NL",
            Self::NO => "NO",
            Self::NZ => "NZ",
            Self::PA => "PA",
            Self::PE => "PE",
            Self::PG => "PG",
            Self::PH => "PH",
            Self::PL => "PL",
            Self::PR => "PR",
            Self::PT => "PT",
            Self::PY => "PY",
            Self::RO => "RO",
            Self::RS => "RS",
            Self::RU => "RU",
            Self::SE => "SE",
            Self::SG => "SG",
            Self::SI => "SI",
            Self::SJ => "SJ",
            Self::SK => "SK",
            Self::SM => "SM",
            Self::SR => "SR",
            Self::SV => "SV",
            Self::TN => "TN",
            Self::TR => "TR",
            Self::UA => "UA",
            Self::US => "US",
            Self::UY => "UY",
            Self::VA => "VA",
            Self::VE => "VE",
            Self::VN => "VN",
            Self::ZA => "ZA",
            Self::ZW => "ZW",
        }
    }
}

impl Display for Country {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.name())
    }
}

impl FromStr for Country {
    type Err = UnknownCountryCode;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "AD" => Ok(Self::AD),
            "AL" => Ok(Self::AL),
            "AM" => Ok(Self::AM),
            "AR" => Ok(Self::AR),
            "AT" => Ok(Self::AT),
            "AU" => Ok(Self::AU),
            "AX" => Ok(Self::AX),
            "BA" => Ok(Self::BA),
            "BB" => Ok(Self::BB),
            "BE" => Ok(Self::BE),
            "BG" => Ok(Self::BG),
            "BJ" => Ok(Self::BJ),
            "BO" => Ok(Self::BO),
            "BR" => Ok(Self::BR),
            "BS" => Ok(Self::BS),
            "BW" => Ok(Self::BW),
            "BY" => Ok(Self::BY),
            "BZ" => Ok(Self::BZ),
            "CA" => Ok(Self::CA),
            "CH" => Ok(Self::CH),
            "CL" => Ok(Self::CL),
            "CN" => Ok(Self::CN),
            "CO" => Ok(Self::CO),
            "CR" => Ok(Self::CR),
            "CU" => Ok(Self::CU),
            "CY" => Ok(Self::CY),
            "CZ" => Ok(Self::CZ),
            "DE" => Ok(Self::DE),
            "DK" => Ok(Self::DK),
            "DO" => Ok(Self::DO),
            "EC" => Ok(Self::EC),
            "EE" => Ok(Self::EE),
            "EG" => Ok(Self::EG),
            "ES" => Ok(Self::ES),
            "FI" => Ok(Self::FI),
            "FO" => Ok(Self::FO),
            "FR" => Ok(Self::FR),
            "GA" => Ok(Self::GA),
            "GB" => Ok(Self::GB),
            "GD" => Ok(Self::GD),
            "GE" => Ok(Self::GE),
            "GG" => Ok(Self::GG),
            "GI" => Ok(Self::GI),
            "GL" => Ok(Self::GL),
            "GM" => Ok(Self::GM),
            "GR" => Ok(Self::GR),
            "GT" => Ok(Self::GT),
            "GY" => Ok(Self::GY),
            "HK" => Ok(Self::HK),
            "HN" => Ok(Self::HN),
            "HR" => Ok(Self::HR),
            "HT" => Ok(Self::HT),
            "HU" => Ok(Self::HU),
            "ID" => Ok(Self::ID),
            "IE" => Ok(Self::IE),
            "IM" => Ok(Self::IM),
            "IS" => Ok(Self::IS),
            "IT" => Ok(Self::IT),
            "JE" => Ok(Self::JE),
            "JM" => Ok(Self::JM),
            "JP" => Ok(Self::JP),
            "KR" => Ok(Self::KR),
            "KZ" => Ok(Self::KZ),
            "LI" => Ok(Self::LI),
            "LS" => Ok(Self::LS),
            "LT" => Ok(Self::LT),
            "LU" => Ok(Self::LU),
            "LV" => Ok(Self::LV),
            "MA" => Ok(Self::MA),
            "MC" => Ok(Self::MC),
            "MD" => Ok(Self::MD),
            "ME" => Ok(Self::ME),
            "MG" => Ok(Self::MG),
            "MK" => Ok(Self::MK),
            "MN" => Ok(Self::MN),
            "MS" => Ok(Self::MS),
            "MT" => Ok(Self::MT),
            "MX" => Ok(Self::MX),
            "MZ" => Ok(Self::MZ),
            "NA" => Ok(Self::NA),
            "NE" => Ok(Self::NE),
            "NG" => Ok(Self::NG),
            "NI" => Ok(Self::NI),
            "NL" => Ok(Self::NL),
            "NO" => Ok(Self::NO),
            "NZ" => Ok(Self::NZ),
            "PA" => Ok(Self::PA),
            "PE" => Ok(Self::PE),
            "PG" => Ok(Self::PG),
            "PH" => Ok(Self::PH),
            "PL" => Ok(Self::PL),
            "PR" => Ok(Self::PR),
            "PT" => Ok(Self::PT),
            "PY" => Ok(Self::PY),
            "RO" => Ok(Self::RO),
            "RS" => Ok(Self::RS),
            "RU" => Ok(Self::RU),
            "SE" => Ok(Self::SE),
            "SG" => Ok(Self::SG),
            "SI" => Ok(Self::SI),
            "SJ" => Ok(Self::SJ),
            "SK" => Ok(Self::SK),
            "SM" => Ok(Self::SM),
            "SR" => Ok(Self::SR),
            "SV" => Ok(Self::SV),
            "TN" => Ok(Self::TN),
            "TR" => Ok(Self::TR),
            "UA" => Ok(Self::UA),
            "US" => Ok(Self::US),
            "UY" => Ok(Self::UY),
            "VA" => Ok(Self::VA),
            "VE" => Ok(Self::VE),
            "VN" => Ok(Self::VN),
            "ZA" => Ok(Self::ZA),
            "ZW" => Ok(Self::ZW),
            _ => Err(UnknownCountryCode(s.to_string())),
        }
    }
}
