#  holidays
#  --------
#  A fast, efficient Python library for generating country, province and state
#  specific sets of holidays on the fly. It aims to make determining whether a
#  specific date is a holiday as fast and flexible as possible.
#
#  Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file)
#           dr-prodigy <dr.prodigy.github@gmail.com> (c) 2017-2023
#           ryanss <ryanssdev@icloud.com> (c) 2014-2017
#  Website: https://github.com/vacanza/holidays
#  License: MIT (see LICENSE file)

from unittest import TestCase

from holidays.countries.jersey import Jersey
from tests.common import CommonCountryTests


class TestJersey(CommonCountryTests, TestCase):
    @classmethod
    def setUpClass(cls):
        super().setUpClass(Jersey)

    def test_special_holidays(self):
        dt = (
            "1957-07-26",
            "1977-06-07",
            "1978-06-27",
            "1981-07-29",
            "1989-05-25",
            "1999-12-31",
            "2001-07-13",
            "2002-06-03",
            "2011-04-29",
            "2012-06-05",
            "2020-05-04",
            "2020-05-08",
            "2021-09-27",
            "2022-06-03",
            "2022-09-19",
            "2023-05-08",
            "2024-07-15",
        )
        dt_observed = (
            "1976-12-28",
            "1977-01-03",
            "1981-12-28",
            "1982-12-28",
            "1983-01-03",
            "1987-12-28",
            "1992-12-28",
            "1993-12-28",
            "1994-01-03",
            "1998-12-28",
            "1999-12-28",
            "2000-01-03",
            "2009-12-28",
        )
        self.assertHoliday(dt, dt_observed)
        self.assertNoNonObservedHoliday(dt_observed)

    def test_new_years_day(self):
        name = "New Year's Day"
        self.assertHolidayName(name, (f"{year}-01-01" for year in self.full_range))
        obs_dts = (
            "2011-01-03",
            "2012-01-02",
            "2017-01-02",
            "2022-01-03",
            "2023-01-02",
        )
        self.assertHolidayName(f"{name} (substitute day)", obs_dts)
        self.assertNoNonObservedHoliday(obs_dts)

    def test_good_friday(self):
        name = "Good Friday"
        self.assertHolidayName(
            name,
            "2020-04-10",
            "2021-04-02",
            "2022-04-15",
            "2023-04-07",
            "2024-03-29",
            "2025-04-18",
        )
        self.assertHolidayName(name, self.full_range)

    def test_easter_monday(self):
        name = "Easter Monday"
        self.assertHolidayName(
            name,
            "2020-04-13",
            "2021-04-05",
            "2022-04-18",
            "2023-04-10",
            "2024-04-01",
            "2025-04-21",
        )
        self.assertHolidayName(name, self.full_range)

    def test_early_may_bank_holiday(self):
        name = "Early May Bank Holiday"
        name_2024 = "May Bank Holiday"
        self.assertHolidayName(
            name,
            "1995-05-08",
            "2020-05-04",
            "2021-05-03",
            "2022-05-02",
            "2023-05-01",
            "2025-05-05",
        )
        self.assertHolidayName(name, range(1980, 2024), range(2025, self.end_year))
        self.assertNoHolidayName(name, range(self.start_year, 1980), 2024)

        self.assertHolidayName(name_2024, "2024-05-06")
        self.assertNoHolidayName(
            name_2024, range(self.start_year, 2024), range(2025, self.end_year)
        )

    def test_liberation_day(self):
        name = "Liberation Day"
        self.assertNonObservedHolidayName(name, (f"{year}-05-09" for year in self.full_range))
        self.assertNoHolidayName(
            name,
            # Sunday, May 9th list 1952-2050 excl. 2010 (65th Anniversary)
            "1954-05-09",
            "1965-05-09",  # 20th Anniversary special? need to check
            "1971-05-09",
            "1976-05-09",
            "1982-05-09",
            "1993-05-09",
            "1999-05-09",
            "2004-05-09",
            "2021-05-09",
            "2027-05-09",
            "2032-05-09",
            "2038-05-09",
            "2049-05-09",
            # Saturday, May 9th list 1952-2010
            "1953-05-09",
            "1959-05-09",
            "1964-05-09",
            "1970-05-09",  # 25th Anniversary special? need to check
            "1981-05-09",
            "1987-05-09",
            "1992-05-09",
            "1998-05-09",
            "2009-05-09",
        )

    def test_spring_bank_holiday(self):
        name = "Spring Bank Holiday"
        self.assertHolidayName(
            name,
            "2002-06-04",
            "2012-06-04",
            "2020-05-25",
            "2021-05-31",
            "2022-06-02",
            "2023-05-29",
            "2024-05-27",
            "2025-05-26",
        )
        self.assertHolidayName(name, range(1970, self.end_year))
        self.assertNoHolidayName(name, range(self.start_year, 1970))

    def test_whit_monday(self):
        name = "Whit Monday"
        self.assertHolidayName(
            name,
            "1964-05-18",
            "1965-06-07",
            "1966-05-30",
            "1967-05-15",
            "1968-06-03",
            "1969-05-26",
        )
        self.assertHolidayName(name, range(self.start_year, 1970))
        self.assertNoHolidayName(name, range(1970, self.end_year))

    def test_summer_bank_holiday(self):
        name = "Summer Bank Holiday"
        self.assertHolidayName(
            name,
            "1964-09-07",
            "1965-09-06",
            "1966-09-05",
            "1967-09-04",
            "1968-09-02",
            "1969-09-01",
            "2020-08-31",
            "2021-08-30",
            "2022-08-29",
            "2023-08-28",
            "2024-08-26",
            "2025-08-25",
        )
        self.assertHolidayName(name, self.full_range)

    def test_2010(self):
        # Wayback Machine of https://www.gov.je/Leisure/Events/WhatsOn/Pages/BankHolidayDates.aspx
        self.assertHolidaysInYear(
            2010,
            ("2010-01-01", "New Year's Day"),
            ("2010-04-02", "Good Friday"),
            ("2010-04-05", "Easter Monday"),
            ("2010-05-03", "Early May Bank Holiday"),
            ("2010-05-09", "Liberation Day"),
            ("2010-05-31", "Spring Bank Holiday"),
            ("2010-08-30", "Summer Bank Holiday"),
            ("2010-12-25", "Christmas Day"),
            ("2010-12-26", "Boxing Day"),
            ("2010-12-27", "Christmas Day (substitute day)"),
            ("2010-12-28", "Boxing Day (substitute day)"),
        )

    def test_christmas_day(self):
        name = "Christmas Day"
        self.assertHolidayName(name, (f"{year}-12-25" for year in self.full_range))
        obs_dts = (
            "2010-12-27",
            "2011-12-27",
            "2016-12-27",
            "2021-12-27",
            "2022-12-27",
        )
        self.assertHolidayName(f"{name} (substitute day)", obs_dts)
        self.assertNoNonObservedHoliday(obs_dts)

    def test_boxing_day(self):
        name = "Boxing Day"
        self.assertHolidayName(name, (f"{year}-12-26" for year in self.full_range))
        obs_dts = (
            "2009-12-28",
            "2010-12-28",
            "2015-12-28",
            "2020-12-28",
            "2021-12-28",
        )
        self.assertHolidayName(f"{name} (substitute day)", obs_dts)
        self.assertNoNonObservedHoliday(obs_dts)

    def test_2011(self):
        # Wayback Machine of https://www.gov.je/Leisure/Events/WhatsOn/Pages/BankHolidayDates.aspx
        self.assertHolidaysInYear(
            2011,
            ("2011-01-01", "New Year's Day"),
            ("2011-01-03", "New Year's Day (substitute day)"),
            ("2011-04-22", "Good Friday"),
            ("2011-04-25", "Easter Monday"),
            ("2011-04-29", "Wedding of William and Catherine"),
            ("2011-05-02", "Early May Bank Holiday"),
            ("2011-05-09", "Liberation Day"),
            ("2011-05-30", "Spring Bank Holiday"),
            ("2011-08-29", "Summer Bank Holiday"),
            ("2011-12-25", "Christmas Day"),
            ("2011-12-26", "Boxing Day"),
            ("2011-12-27", "Christmas Day (substitute day)"),
        )

    def test_2012(self):
        # Wayback Machine of https://www.gov.je/Leisure/Events/WhatsOn/Pages/BankHolidayDates.aspx
        self.assertHolidaysInYear(
            2012,
            ("2012-01-01", "New Year's Day"),
            ("2012-01-02", "New Year's Day (substitute day)"),
            ("2012-04-06", "Good Friday"),
            ("2012-04-09", "Easter Monday"),
            ("2012-05-07", "Early May Bank Holiday"),
            ("2012-05-09", "Liberation Day"),
            ("2012-06-04", "Spring Bank Holiday"),
            ("2012-06-05", "Queen's Diamond Jubilee"),
            ("2012-08-27", "Summer Bank Holiday"),
            ("2012-12-25", "Christmas Day"),
            ("2012-12-26", "Boxing Day"),
        )

    def test_2013(self):
        # Wayback Machine of https://www.gov.je/Leisure/Events/WhatsOn/Pages/BankHolidayDates.aspx
        self.assertHolidaysInYear(
            2013,
            ("2013-01-01", "New Year's Day"),
            ("2013-03-29", "Good Friday"),
            ("2013-04-01", "Easter Monday"),
            ("2013-05-06", "Early May Bank Holiday"),
            ("2013-05-09", "Liberation Day"),
            ("2013-05-27", "Spring Bank Holiday"),
            ("2013-08-26", "Summer Bank Holiday"),
            ("2013-12-25", "Christmas Day"),
            ("2013-12-26", "Boxing Day"),
        )

    def test_2014(self):
        # Wayback Machine of https://www.gov.je/Leisure/Events/WhatsOn/Pages/BankHolidayDates.aspx
        self.assertHolidaysInYear(
            2014,
            ("2014-01-01", "New Year's Day"),
            ("2014-04-18", "Good Friday"),
            ("2014-04-21", "Easter Monday"),
            ("2014-05-05", "Early May Bank Holiday"),
            ("2014-05-09", "Liberation Day"),
            ("2014-05-26", "Spring Bank Holiday"),
            ("2014-08-25", "Summer Bank Holiday"),
            ("2014-12-25", "Christmas Day"),
            ("2014-12-26", "Boxing Day"),
        )

    def test_2015(self):
        # Wayback Machine of https://www.gov.je/Leisure/Events/WhatsOn/Pages/BankHolidayDates.aspx
        self.assertHolidaysInYear(
            2015,
            ("2015-01-01", "New Year's Day"),
            ("2015-04-03", "Good Friday"),
            ("2015-04-06", "Easter Monday"),
            ("2015-05-04", "Early May Bank Holiday"),
            ("2015-05-09", "Liberation Day"),
            ("2015-05-25", "Spring Bank Holiday"),
            ("2015-08-31", "Summer Bank Holiday"),
            ("2015-12-25", "Christmas Day"),
            ("2015-12-26", "Boxing Day"),
            ("2015-12-28", "Boxing Day (substitute day)"),
        )

    def test_2016(self):
        # Wayback Machine of https://www.gov.je/Leisure/Events/WhatsOn/Pages/BankHolidayDates.aspx
        self.assertHolidaysInYear(
            2016,
            ("2016-01-01", "New Year's Day"),
            ("2016-03-25", "Good Friday"),
            ("2016-03-28", "Easter Monday"),
            ("2016-05-02", "Early May Bank Holiday"),
            ("2016-05-09", "Liberation Day"),
            ("2016-05-30", "Spring Bank Holiday"),
            ("2016-08-29", "Summer Bank Holiday"),
            ("2016-12-25", "Christmas Day"),
            ("2016-12-26", "Boxing Day"),
            ("2016-12-27", "Christmas Day (substitute day)"),
        )

    def test_2017(self):
        # Wayback Machine of https://www.gov.je/Leisure/Events/WhatsOn/Pages/BankHolidayDates.aspx
        self.assertHolidaysInYear(
            2017,
            ("2017-01-01", "New Year's Day"),
            ("2017-01-02", "New Year's Day (substitute day)"),
            ("2017-04-14", "Good Friday"),
            ("2017-04-17", "Easter Monday"),
            ("2017-05-01", "Early May Bank Holiday"),
            ("2017-05-09", "Liberation Day"),
            ("2017-05-29", "Spring Bank Holiday"),
            ("2017-08-28", "Summer Bank Holiday"),
            ("2017-12-25", "Christmas Day"),
            ("2017-12-26", "Boxing Day"),
        )

    def test_2018(self):
        # Wayback Machine of https://www.gov.je/Leisure/Events/WhatsOn/Pages/BankHolidayDates.aspx
        self.assertHolidaysInYear(
            2018,
            ("2018-01-01", "New Year's Day"),
            ("2018-03-30", "Good Friday"),
            ("2018-04-02", "Easter Monday"),
            ("2018-05-07", "Early May Bank Holiday"),
            ("2018-05-09", "Liberation Day"),
            ("2018-05-28", "Spring Bank Holiday"),
            ("2018-08-27", "Summer Bank Holiday"),
            ("2018-12-25", "Christmas Day"),
            ("2018-12-26", "Boxing Day"),
        )

    def test_2019(self):
        # Wayback Machine of https://www.gov.je/Leisure/Events/WhatsOn/Pages/BankHolidayDates.aspx
        self.assertHolidaysInYear(
            2019,
            ("2019-01-01", "New Year's Day"),
            ("2019-04-19", "Good Friday"),
            ("2019-04-22", "Easter Monday"),
            ("2019-05-06", "Early May Bank Holiday"),
            ("2019-05-09", "Liberation Day"),
            ("2019-05-27", "Spring Bank Holiday"),
            ("2019-08-26", "Summer Bank Holiday"),
            ("2019-12-25", "Christmas Day"),
            ("2019-12-26", "Boxing Day"),
        )

    def test_2020(self):
        # Wayback Machine of https://www.gov.je/Leisure/Events/WhatsOn/Pages/BankHolidayDates.aspx
        self.assertHolidaysInYear(
            2020,
            ("2020-01-01", "New Year's Day"),
            ("2020-04-10", "Good Friday"),
            ("2020-04-13", "Easter Monday"),
            ("2020-05-04", "Early May Bank Holiday"),
            ("2020-05-08", "75th Anniversary of VE Day"),
            ("2020-05-09", "Liberation Day"),
            ("2020-05-25", "Spring Bank Holiday"),
            ("2020-08-31", "Summer Bank Holiday"),
            ("2020-12-25", "Christmas Day"),
            ("2020-12-26", "Boxing Day"),
            ("2020-12-28", "Boxing Day (substitute day)"),
        )

    def test_2021(self):
        # Wayback Machine of https://www.gov.je/Leisure/Events/WhatsOn/Pages/BankHolidayDates.aspx
        self.assertHolidaysInYear(
            2021,
            ("2021-01-01", "New Year's Day"),
            ("2021-04-02", "Good Friday"),
            ("2021-04-05", "Easter Monday"),
            ("2021-05-03", "Early May Bank Holiday"),
            ("2021-05-31", "Spring Bank Holiday"),
            ("2021-08-30", "Summer Bank Holiday"),
            ("2021-09-27", "Corn Riots Anniversary"),
            ("2021-12-25", "Christmas Day"),
            ("2021-12-26", "Boxing Day"),
            ("2021-12-27", "Christmas Day (substitute day)"),
            ("2021-12-28", "Boxing Day (substitute day)"),
        )

    def test_2022(self):
        # Wayback Machine of https://www.gov.je/Leisure/Events/WhatsOn/Pages/BankHolidayDates.aspx
        self.assertHolidaysInYear(
            2022,
            ("2022-01-01", "New Year's Day"),
            ("2022-01-03", "New Year's Day (substitute day)"),
            ("2022-04-15", "Good Friday"),
            ("2022-04-18", "Easter Monday"),
            ("2022-05-02", "Early May Bank Holiday"),
            ("2022-05-09", "Liberation Day"),
            ("2022-06-02", "Spring Bank Holiday"),
            ("2022-06-03", "Queen's Platinum Jubilee"),
            ("2022-08-29", "Summer Bank Holiday"),
            ("2022-09-19", "Funeral of Her Majesty Queen Elizabeth II"),
            ("2022-12-25", "Christmas Day"),
            ("2022-12-26", "Boxing Day"),
            ("2022-12-27", "Christmas Day (substitute day)"),
        )

    def test_2023(self):
        # https://www.gov.je/Leisure/Events/WhatsOn/Pages/BankHolidayDates.aspx
        self.assertHolidaysInYear(
            2023,
            ("2023-01-01", "New Year's Day"),
            ("2023-01-02", "New Year's Day (substitute day)"),
            ("2023-04-07", "Good Friday"),
            ("2023-04-10", "Easter Monday"),
            ("2023-05-01", "Early May Bank Holiday"),
            ("2023-05-08", "Coronation of His Majesty King Charles III"),
            ("2023-05-09", "Liberation Day"),
            ("2023-05-29", "Spring Bank Holiday"),
            ("2023-08-28", "Summer Bank Holiday"),
            ("2023-12-25", "Christmas Day"),
            ("2023-12-26", "Boxing Day"),
        )

    def test_2024(self):
        # https://www.gov.je/Leisure/Events/WhatsOn/Pages/BankHolidayDates.aspx
        self.assertHolidaysInYear(
            2024,
            ("2024-01-01", "New Year's Day"),
            ("2024-03-29", "Good Friday"),
            ("2024-04-01", "Easter Monday"),
            ("2024-05-06", "May Bank Holiday"),
            ("2024-05-09", "Liberation Day"),
            ("2024-05-27", "Spring Bank Holiday"),
            ("2024-07-15", "The visit of His Majesty King Charles III and Queen Camilla"),
            ("2024-08-26", "Summer Bank Holiday"),
            ("2024-12-25", "Christmas Day"),
            ("2024-12-26", "Boxing Day"),
        )

    def test_2025(self):
        # https://www.gov.je/Leisure/Events/WhatsOn/Pages/BankHolidayDates.aspx
        self.assertHolidaysInYear(
            2025,
            ("2025-01-01", "New Year's Day"),
            ("2025-04-18", "Good Friday"),
            ("2025-04-21", "Easter Monday"),
            ("2025-05-05", "Early May Bank Holiday"),
            ("2025-05-09", "Liberation Day"),
            ("2025-05-26", "Spring Bank Holiday"),
            ("2025-08-25", "Summer Bank Holiday"),
            ("2025-12-25", "Christmas Day"),
            ("2025-12-26", "Boxing Day"),
        )
