{--
  references:
  https://en.wikipedia.org/wiki/Public_holidays_in_Germany
  https://publicholidays.de/
--}
{-# LANGUAGE OverloadedStrings #-}

module Holidays.Germany (
  holidays,
) where

import Data.Time

import Holidays.Base
import Holidays.DateFinder
import Holidays.DateTransform

holidays :: [Region] -> ([Year -> Holiday], [DateTransform])
holidays :: [Text] -> ([Year -> Holiday], [DateTransform])
holidays [Text]
regions =
  ( [[Year -> Holiday]] -> [Year -> Holiday]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
      [ [Year -> Holiday]
federalHolidays,
        [Text] -> [Year -> Holiday]
regionalHolidays [Text]
regions
      ],
    []
  )

federalHolidays :: [Year -> Holiday]
federalHolidays :: [Year -> Holiday]
federalHolidays =
  [ Text -> Day -> Holiday
hday Text
"new_years_day" (Day -> Holiday) -> (Year -> Day) -> Year -> Holiday
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Year -> Day
newYearsDay,
    Text -> Day -> Holiday
hday Text
"good_friday" (Day -> Holiday) -> (Year -> Day) -> Year -> Holiday
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Year -> Day
goodFriday,
    Text -> Day -> Holiday
hday Text
"easter_monday" (Day -> Holiday) -> (Year -> Day) -> Year -> Holiday
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Year -> Day
easterMonday,
    Text -> Day -> Holiday
hday Text
"labour_day" (Day -> Holiday) -> (Year -> Day) -> Year -> Holiday
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Year -> Day
workersDay,
    Text -> Day -> Holiday
hday Text
"ascension_day" (Day -> Holiday) -> (Year -> Day) -> Year -> Holiday
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Year -> Day
ascensionDay,
    Text -> Day -> Holiday
hday Text
"whit_monday" (Day -> Holiday) -> (Year -> Day) -> Year -> Holiday
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Year
50 `days`) ((Year -> Maybe DayOfWeek -> Day) -> Day)
-> (Year -> Year -> Maybe DayOfWeek -> Day) -> Year -> Day
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Day -> Year -> Maybe DayOfWeek -> Day
after (Day -> Year -> Maybe DayOfWeek -> Day)
-> (Year -> Day) -> Year -> Year -> Maybe DayOfWeek -> Day
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Year -> Day
easterSunday,
    Text -> Day -> Holiday
hday Text
"germany_unity_day" (Day -> Holiday) -> (Year -> Day) -> Year -> Holiday
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DayOfMonth -> Year -> Day
oct DayOfMonth
3,
    Text -> Day -> Holiday
hday Text
"christmas_day" (Day -> Holiday) -> (Year -> Day) -> Year -> Holiday
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Year -> Day
christmasDay,
    Text -> Day -> Holiday
hday Text
"second_day_of_christmas" (Day -> Holiday) -> (Year -> Day) -> Year -> Holiday
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Year -> Day
boxingDay
  ]

regionalHolidays :: [Region] -> [Year -> Holiday]
regionalHolidays :: [Text] -> [Year -> Holiday]
regionalHolidays =
  (Text -> [Year -> Holiday]) -> [Text] -> [Year -> Holiday]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap
    ( \Text
r -> case Text
r of
        Text
"BW" -> [Year -> Holiday]
badenWurttembergHolidays
        Text
"BY" -> [Year -> Holiday]
bavariaHolidays
        Text
"BE" -> [Year -> Holiday]
berlinHolidays
        Text
"BB" -> [Year -> Holiday]
brandenburgHolidays
        Text
"HB" -> [Year -> Holiday]
bremenHolidays
        Text
"HH" -> [Year -> Holiday]
hamburgHolidays
        Text
"HE" -> [Year -> Holiday]
hesseHolidays
        Text
"MV" -> [Year -> Holiday]
mecklenburgVorpommernHolidays
        Text
"NI" -> [Year -> Holiday]
lowerSaxonyHolidays
        Text
"NW" -> [Year -> Holiday]
northRhineWestphaliaHolidays
        Text
"RP" -> [Year -> Holiday]
rhinelandPalatinateHolidays
        Text
"SL" -> [Year -> Holiday]
saarlandHolidays
        Text
"SN" -> [Year -> Holiday]
saxonyHolidays
        Text
"ST" -> [Year -> Holiday]
saxonyAnhaltHolidays
        Text
"SH" -> [Year -> Holiday]
schleswigHolsteinHolidays
        Text
"TH" -> [Year -> Holiday]
thuringiaHolidays
        Text
_ -> []
    )

-- common holidays
epiphany :: Year -> Holiday
epiphany :: Year -> Holiday
epiphany = Text -> Day -> Holiday
hday Text
"epiphany" (Day -> Holiday) -> (Year -> Day) -> Year -> Holiday
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DayOfMonth -> Year -> Day
jan DayOfMonth
6

corpusChristi :: Year -> Holiday
corpusChristi :: Year -> Holiday
corpusChristi = Text -> Day -> Holiday
hday Text
"corpus_christi" (Day -> Holiday) -> (Year -> Day) -> Year -> Holiday
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Year
60 `days`) ((Year -> Maybe DayOfWeek -> Day) -> Day)
-> (Year -> Year -> Maybe DayOfWeek -> Day) -> Year -> Day
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Day -> Year -> Maybe DayOfWeek -> Day
after (Day -> Year -> Maybe DayOfWeek -> Day)
-> (Year -> Day) -> Year -> Year -> Maybe DayOfWeek -> Day
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Year -> Day
easterSunday

allSaintsDay :: Year -> Holiday
allSaintsDay :: Year -> Holiday
allSaintsDay = Text -> Day -> Holiday
hday Text
"all_saints_day" (Day -> Holiday) -> (Year -> Day) -> Year -> Holiday
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DayOfMonth -> Year -> Day
nov DayOfMonth
1

assumptionDay :: Year -> Holiday
assumptionDay :: Year -> Holiday
assumptionDay = Text -> Day -> Holiday
hday Text
"assumption_day" (Day -> Holiday) -> (Year -> Day) -> Year -> Holiday
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DayOfMonth -> Year -> Day
aug DayOfMonth
15

internationalWomensDay :: Year -> Holiday
internationalWomensDay :: Year -> Holiday
internationalWomensDay = Text -> Day -> Holiday
hday Text
"international_womens_day" (Day -> Holiday) -> (Year -> Day) -> Year -> Holiday
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DayOfMonth -> Year -> Day
mar DayOfMonth
8

reformationDay :: Year -> Holiday
reformationDay :: Year -> Holiday
reformationDay = Text -> Day -> Holiday
hday Text
"reformation_day" (Day -> Holiday) -> (Year -> Day) -> Year -> Holiday
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DayOfMonth -> Year -> Day
oct DayOfMonth
31

badenWurttembergHolidays :: [Year -> Holiday]
badenWurttembergHolidays :: [Year -> Holiday]
badenWurttembergHolidays =
  [ Year -> Holiday
epiphany,
    Year -> Holiday
corpusChristi,
    Year -> Holiday
allSaintsDay
  ]

bavariaHolidays :: [Year -> Holiday]
bavariaHolidays :: [Year -> Holiday]
bavariaHolidays =
  [ Year -> Holiday
epiphany,
    Year -> Holiday
corpusChristi,
    Year -> Holiday
assumptionDay,
    Year -> Holiday
allSaintsDay
  ]

berlinHolidays :: [Year -> Holiday]
berlinHolidays :: [Year -> Holiday]
berlinHolidays =
  [ Year -> Holiday
internationalWomensDay,
    Year -> Holiday
allSaintsDay,
    Text -> Day -> Holiday
hday Text
"80th_anniversary_of_end_of_world_war_2" (Day -> Holiday) -> (Year -> Day) -> Year -> Holiday
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Year -> Bool) -> Day -> Day
years (Year -> Year -> Bool
forall a. Eq a => a -> a -> Bool
== Year
2025) (Day -> Day) -> (Year -> Day) -> Year -> Day
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DayOfMonth -> Year -> Day
may DayOfMonth
8
  ]

brandenburgHolidays :: [Year -> Holiday]
brandenburgHolidays :: [Year -> Holiday]
brandenburgHolidays =
  [ Text -> Day -> Holiday
hday Text
"easter_sunday" (Day -> Holiday) -> (Year -> Day) -> Year -> Holiday
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Year -> Day
easterSunday,
    Text -> Day -> Holiday
hday Text
"whit_sunday" (Day -> Holiday) -> (Year -> Day) -> Year -> Holiday
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Year
49 `days`) ((Year -> Maybe DayOfWeek -> Day) -> Day)
-> (Year -> Year -> Maybe DayOfWeek -> Day) -> Year -> Day
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Day -> Year -> Maybe DayOfWeek -> Day
after (Day -> Year -> Maybe DayOfWeek -> Day)
-> (Year -> Day) -> Year -> Year -> Maybe DayOfWeek -> Day
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Year -> Day
easterSunday,
    Year -> Holiday
reformationDay
  ]

bremenHolidays :: [Year -> Holiday]
bremenHolidays :: [Year -> Holiday]
bremenHolidays =
  [ Year -> Holiday
reformationDay
  ]

hamburgHolidays :: [Year -> Holiday]
hamburgHolidays :: [Year -> Holiday]
hamburgHolidays =
  [ Year -> Holiday
reformationDay
  ]

hesseHolidays :: [Year -> Holiday]
hesseHolidays :: [Year -> Holiday]
hesseHolidays =
  [Year -> Holiday
corpusChristi]

mecklenburgVorpommernHolidays :: [Year -> Holiday]
mecklenburgVorpommernHolidays :: [Year -> Holiday]
mecklenburgVorpommernHolidays =
  [ Year -> Holiday
internationalWomensDay,
    Year -> Holiday
reformationDay
  ]

lowerSaxonyHolidays :: [Year -> Holiday]
lowerSaxonyHolidays :: [Year -> Holiday]
lowerSaxonyHolidays =
  [ Year -> Holiday
reformationDay
  ]

northRhineWestphaliaHolidays :: [Year -> Holiday]
northRhineWestphaliaHolidays :: [Year -> Holiday]
northRhineWestphaliaHolidays =
  [ Year -> Holiday
corpusChristi,
    Year -> Holiday
allSaintsDay
  ]

rhinelandPalatinateHolidays :: [Year -> Holiday]
rhinelandPalatinateHolidays :: [Year -> Holiday]
rhinelandPalatinateHolidays =
  [ Year -> Holiday
corpusChristi,
    Year -> Holiday
allSaintsDay
  ]

saarlandHolidays :: [Year -> Holiday]
saarlandHolidays :: [Year -> Holiday]
saarlandHolidays =
  [ Year -> Holiday
corpusChristi,
    Year -> Holiday
assumptionDay,
    Year -> Holiday
allSaintsDay
  ]

saxonyHolidays :: [Year -> Holiday]
saxonyHolidays :: [Year -> Holiday]
saxonyHolidays =
  [ Text -> Day -> Holiday
hday Text
"repentance_and_prayer_day" (Day -> Holiday) -> (Year -> Day) -> Year -> Holiday
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Year
2 `wed`) ((Year -> Maybe DayOfWeek -> Day) -> Day)
-> (Year -> Year -> Maybe DayOfWeek -> Day) -> Year -> Day
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Day -> Year -> Maybe DayOfWeek -> Day
before (Day -> Year -> Maybe DayOfWeek -> Day)
-> (Year -> Day) -> Year -> Year -> Maybe DayOfWeek -> Day
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Year
4 `sun`) ((Year -> Maybe DayOfWeek -> Day) -> Day)
-> (Year -> Year -> Maybe DayOfWeek -> Day) -> Year -> Day
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Day -> Year -> Maybe DayOfWeek -> Day
before (Day -> Year -> Maybe DayOfWeek -> Day)
-> (Year -> Day) -> Year -> Year -> Maybe DayOfWeek -> Day
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Year -> Day
christmasDay
  ]

saxonyAnhaltHolidays :: [Year -> Holiday]
saxonyAnhaltHolidays :: [Year -> Holiday]
saxonyAnhaltHolidays =
  [ Year -> Holiday
epiphany,
    Year -> Holiday
reformationDay
  ]

schleswigHolsteinHolidays :: [Year -> Holiday]
schleswigHolsteinHolidays :: [Year -> Holiday]
schleswigHolsteinHolidays =
  []

thuringiaHolidays :: [Year -> Holiday]
thuringiaHolidays :: [Year -> Holiday]
thuringiaHolidays =
  [ Text -> Day -> Holiday
hday Text
"worlds_children_day" (Day -> Holiday) -> (Year -> Day) -> Year -> Holiday
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DayOfMonth -> Year -> Day
sep DayOfMonth
20
  ]