-- Copyright (c) 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the BSD-style license found in the
-- LICENSE file in the root directory of this source tree.

{-# LANGUAGE GADTs #-}
{-# LANGUAGE NoRebindableSyntax #-}
{-# LANGUAGE OverloadedStrings #-}

module Duckling.Time.GA.Rules
  ( rules
  ) where

import Data.Text (Text)
import Prelude

import Duckling.Dimensions.Types
import Duckling.Duration.Helpers (isGrain)
import Duckling.Numeral.Helpers (parseInt)
import Duckling.Regex.Types
import Duckling.Time.Helpers
import Duckling.Types
import qualified Duckling.Ordinal.Types as TOrdinal
import qualified Duckling.TimeGrain.Types as TG

ruleArInn :: Rule
ruleArInn = Rule
  { name = "arÃº innÃ©"
  , pattern =
    [ regex "ar(Ãº|u) inn(Ã©|e)"
    ]
  , prod = \_ -> tt . cycleNth TG.Day $ - 2
  }

ruleNollaigNaMban :: Rule
ruleNollaigNaMban = Rule
  { name = "Nollaig na mBan"
  , pattern =
    [ regex "(l(Ã¡|a) |an )?nollaig (bheag|na mban)"
    ]
  , prod = \_ -> tt $ monthDay 1 6
  }

ruleInniu :: Rule
ruleInniu = Rule
  { name = "inniu"
  , pattern =
    [ regex "inniu"
    ]
  , prod = \_ -> tt today
  }

ruleAnOrdinalCycleINdiaidhTime :: Rule
ruleAnOrdinalCycleINdiaidhTime = Rule
  { name = "an <ordinal> <cycle> i ndiaidh <time>"
  , pattern =
    [ regex "an"
    , dimension Ordinal
    , dimension TimeGrain
    , regex "(i ndiaidh|tar (Ã©|e)is)"
    , dimension Time
    ]
  , prod = \tokens -> case tokens of
      (_:Token Ordinal od:Token TimeGrain grain:_:Token Time td:_) ->
        tt $ cycleNthAfter True grain (TOrdinal.value od - 1) td
      _ -> Nothing
  }

ruleInn :: Rule
ruleInn = Rule
  { name = "innÃ©"
  , pattern =
    [ regex "inn(Ã©|e)"
    ]
  , prod = \_ -> tt . cycleNth TG.Day $ - 1
  }

ruleLFhileBrde :: Rule
ruleLFhileBrde = Rule
  { name = "LÃ¡ FhÃ©ile BrÃde"
  , pattern =
    [ regex "(l(Ã¡|a) )?(fh(e|Ã©)ile|'?le) bh?r(Ã|i)de"
    ]
  , prod = \_ -> tt $ monthDay 2 1
  }

ruleLFhileVailintn :: Rule
ruleLFhileVailintn = Rule
  { name = "LÃ¡ FhÃ©ile VailintÃn"
  , pattern =
    [ regex "(l(Ã¡|a) )?(fh(e|Ã©)ile|'?le) vailint(Ã|i)n"
    ]
  , prod = \_ -> tt $ monthDay 2 14
  }

ruleTimeSeo :: Rule
ruleTimeSeo = Rule
  { name = "<time> seo"
  , pattern =
    [ dimension Time
    , regex "seo"
    ]
  , prod = \tokens -> case tokens of
      (Token Time td:_) ->
        tt $ predNth 0 False td
      _ -> Nothing
  }

ruleTimeSeoChaite :: Rule
ruleTimeSeoChaite = Rule
  { name = "<time> seo chaite"
  , pattern =
    [ dimension Time
    , regex "seo ch?aite"
    ]
  , prod = \tokens -> case tokens of
      (Token Time td:_) ->
        tt $ predNth (-1) False td
      _ -> Nothing
  }

ruleTimeSeoChugainn :: Rule
ruleTimeSeoChugainn = Rule
  { name = "<time> seo chugainn"
  , pattern =
    [ Predicate isNotLatent
    , regex "seo (chugainn|at(a|Ã¡) ag teacht)"
    ]
  , prod = \tokens -> case tokens of
      (Token Time td:_) ->
        tt $ predNth 0 True td
      _ -> Nothing
  }

ruleAmrach :: Rule
ruleAmrach = Rule
  { name = "amÃ¡rach"
  , pattern =
    [ regex "am(Ã¡|a)rach"
    ]
  , prod = \_ -> tt $ cycleNth TG.Day 1
  }

ruleYearLatent2 :: Rule
ruleYearLatent2 = Rule
  { name = "year (latent)"
  , pattern =
    [ Predicate $ isIntegerBetween 2101 10000
    ]
  , prod = \tokens -> case tokens of
      (token:_) -> do
        n <- getIntValue token
        tt . mkLatent $ year n
      _ -> Nothing
  }

ruleOrdinalRithe :: Rule
ruleOrdinalRithe = Rule
  { name = "<ordinal> rÃ¡ithe"
  , pattern =
    [ dimension Ordinal
    , Predicate $ isGrain TG.Quarter
    ]
  , prod = \tokens -> case tokens of
      (token:_) -> do
        n <- getIntValue token
        tt . cycleNthAfter True TG.Quarter (n - 1) $
          cycleNth TG.Year 0
      _ -> Nothing
  }

ruleAnnaCycleRoimhTime :: Rule
ruleAnnaCycleRoimhTime = Rule
  { name = "(an|na) <cycle> roimh <time>"
  , pattern =
    [ regex "the"
    , dimension TimeGrain
    , regex "roimh"
    , dimension Time
    ]
  , prod = \tokens -> case tokens of
      (_:Token TimeGrain grain:_:Token Time td:_) ->
        tt $ cycleNthAfter False grain (-1) td
      _ -> Nothing
  }

ruleCycleShin :: Rule
ruleCycleShin = Rule
  { name = "<cycle> Ã³ shin"
  , pattern =
    [ dimension TimeGrain
    , regex "(Ã³|o) shin"
    ]
  , prod = \tokens -> case tokens of
      (Token TimeGrain grain:_) ->
        tt . cycleNth grain $ 1
      _ -> Nothing
  }

ruleDdmm :: Rule
ruleDdmm = Rule
  { name = "dd/mm"
  , pattern =
    [ regex "(3[01]|[12]\\d|0?[1-9])/(0?[1-9]|1[0-2])"
    ]
  , prod = \tokens -> case tokens of
      (Token RegexMatch (GroupMatch (m1:m2:_)):_) -> do
        m <- parseInt m2
        d <- parseInt m1
        tt $ monthDay m d
      _ -> Nothing
  }

ruleIGceannCycle :: Rule
ruleIGceannCycle = Rule
  { name = "i gceann <cycle>"
  , pattern =
    [ regex "(i|faoi) g?ch?eann"
    , Predicate $ isIntegerBetween 1 9999
    , dimension TimeGrain
    ]
  , prod = \tokens -> case tokens of
      (_:Token Ordinal od:Token TimeGrain grain:_) ->
        tt $ cycleN True grain (TOrdinal.value od)
      _ -> Nothing
  }

ruleAnCycleDeTime :: Rule
ruleAnCycleDeTime = Rule
  { name = "an <cycle> de <time>"
  , pattern =
    [ regex "an"
    , dimension TimeGrain
    , regex "d[e']"
    , dimension Time
    ]
  , prod = \tokens -> case tokens of
      (_:Token TimeGrain grain:_:Token Time td:_) ->
        tt $ cycleNthAfter True grain 0 td
      _ -> Nothing
  }

ruleDayofmonthordinalNamedmonth :: Rule
ruleDayofmonthordinalNamedmonth = Rule
  { name = "<day-of-month>(ordinal) <named-month>"
  , pattern =
    [ Predicate isDOMOrdinal
    , Predicate isAMonth
    ]
  , prod = \tokens -> case tokens of
      (token:Token Time td:_) -> Token Time <$> intersectDOM td token
      _ -> Nothing
  }

ruleIntersectBy :: Rule
ruleIntersectBy = Rule
  { name = "intersect by \",\""
  , pattern =
    [ Predicate isNotLatent
    , regex ","
    , Predicate isNotLatent
    ]
  , prod = \tokens -> case tokens of
      (Token Time td1:_:Token Time td2:_) ->
        Token Time <$> intersect td1 td2
      _ -> Nothing
  }

ruleOrdinalRitheYear :: Rule
ruleOrdinalRitheYear = Rule
  { name = "<ordinal> rÃ¡ithe <year>"
  , pattern =
    [ dimension Ordinal
    , Predicate $ isGrain TG.Quarter
    , dimension Time
    ]
  , prod = \tokens -> case tokens of
      (Token Ordinal od:_:Token Time td:_) ->
        tt $ cycleNthAfter False TG.Quarter (TOrdinal.value od - 1) td
      _ -> Nothing
  }

ruleCycleInniu :: Rule
ruleCycleInniu = Rule
  { name = "<cycle> Ã³ inniu"
  , pattern =
    [ Predicate $ isIntegerBetween 1 9999
    , dimension TimeGrain
    , regex "(Ã³|o)(n l(Ã¡|a) (at(Ã¡|a) )?)?inniu"
    ]
  , prod = \tokens -> case tokens of
      (token:Token TimeGrain grain:_) -> do
        v <- getIntValue token
        tt $ cycleN True grain v
      _ -> Nothing
  }

ruleOrdinalCycleINdiaidhTime :: Rule
ruleOrdinalCycleINdiaidhTime = Rule
  { name = "<ordinal> <cycle> i ndiaidh <time>"
  , pattern =
    [ dimension Ordinal
    , dimension TimeGrain
    , regex "(i ndiaidh|tar (Ã©|e)is)"
    , dimension Time
    ]
  , prod = \tokens -> case tokens of
      (Token Ordinal od:Token TimeGrain grain:_:Token Time td:_) ->
        tt $ cycleNthAfter True grain (TOrdinal.value od - 1) td
      _ -> Nothing
  }

ruleAnDayofmonthOrdinal :: Rule
ruleAnDayofmonthOrdinal = Rule
  { name = "an <day-of-month> (ordinal)"
  , pattern =
    [ regex "an|na"
    , Predicate isDOMOrdinal
    ]
  , prod = \tokens -> case tokens of
      (_:token:_) -> do
        n <- getIntValue token
        tt $ dayOfMonth n
      _ -> Nothing
  }

ruleIntersect :: Rule
ruleIntersect = Rule
  { name = "intersect"
  , pattern =
    [ Predicate isNotLatent
    , Predicate isNotLatent
    ]
  , prod = \tokens -> case tokens of
      (Token Time td1:Token Time td2:_) ->
        Token Time <$> intersect td1 td2
      _ -> Nothing
  }

ruleAnOrdinalCycleDeTime :: Rule
ruleAnOrdinalCycleDeTime = Rule
  { name = "an <ordinal> <cycle> de <time>"
  , pattern =
    [ regex "an"
    , dimension Ordinal
    , dimension TimeGrain
    , regex "d[e']"
    , dimension Time
    ]
  , prod = \tokens -> case tokens of
      (_:Token Ordinal od:Token TimeGrain grain:_:Token Time td:_) ->
        tt $ cycleNthAfter True grain (TOrdinal.value od - 1) td
      _ -> Nothing
  }

ruleLNaNaithreacha :: Rule
ruleLNaNaithreacha = Rule
  { name = "LÃ¡ na nAithreacha"
  , pattern =
    [ regex "l(Ã¡|a) na naithreacha"
    ]
  , prod = \_ -> tt $ nthDOWOfMonth 2 7 6
  }

ruleArAmrach :: Rule
ruleArAmrach = Rule
  { name = "arÃº amÃ¡rach"
  , pattern =
    [ regex "ar(Ãº|u) am(Ã¡|a)rach"
    ]
  , prod = \_ -> tt $ cycleNth TG.Day 2
  }

ruleOrdinalCycleDeTime :: Rule
ruleOrdinalCycleDeTime = Rule
  { name = "<ordinal> <cycle> de <time>"
  , pattern =
    [ dimension Ordinal
    , dimension TimeGrain
    , regex "d[e']"
    , dimension Time
    ]
  , prod = \tokens -> case tokens of
      (Token Ordinal od:Token TimeGrain grain:_:Token Time td:_) ->
        tt $ cycleNthAfter True grain (TOrdinal.value od - 1) td
      _ -> Nothing
  }

ruleYyyymmdd :: Rule
ruleYyyymmdd = Rule
  { name = "yyyy-mm-dd"
  , pattern =
    [ regex "(\\d{2,4})-(0?[1-9]|1[0-2])-(3[01]|[12]\\d|0?[1-9])"
    ]
  , prod = \tokens -> case tokens of
      (Token RegexMatch (GroupMatch (m1:m2:m3:_)):_) -> do
        y <- parseInt m1
        m <- parseInt m2
        d <- parseInt m3
        tt $ yearMonthDay y m d
      _ -> Nothing
  }

ruleArDate :: Rule
ruleArDate = Rule
  { name = "ar <date>"
  , pattern =
    [ regex "ar"
    , dimension Time
    ]
  , prod = \tokens -> case tokens of
      (_:x:_) -> Just x
      _ -> Nothing
  }

ruleAnNollaig :: Rule
ruleAnNollaig = Rule
  { name = "An Nollaig"
  , pattern =
    [ regex "(l(Ã¡|a) |an )?(nollai?g)"
    ]
  , prod = \_ -> tt $ monthDay 12 25
  }

ruleOnANamedday :: Rule
ruleOnANamedday = Rule
  { name = "on a named-day"
  , pattern =
    [ regex "ar an"
    , Predicate isADayOfWeek
    ]
  , prod = \tokens -> case tokens of
      (_:x:_) -> Just x
      _ -> Nothing
  }

ruleYearLatent :: Rule
ruleYearLatent = Rule
  { name = "year (latent)"
  , pattern =
    [ Predicate $ isIntegerBetween 1 999
    ]
  , prod = \tokens -> case tokens of
      (token:_) -> do
        n <- getIntValue token
        tt . mkLatent $ year n
      _ -> Nothing
  }

ruleAnois :: Rule
ruleAnois = Rule
  { name = "anois"
  , pattern =
    [ regex "anois|(ag an (t-?)?am seo)"
    ]
  , prod = \_ -> tt now
  }

ruleLFhilePdraig :: Rule
ruleLFhilePdraig = Rule
  { name = "LÃ¡ FhÃ©ile PÃ¡draig"
  , pattern =
    [ regex "(l(Ã¡|a) )?(fh(e|Ã©)ile|'?le) ph?(Ã¡|a)draig"
    ]
  , prod = \_ -> tt $ monthDay 3 17
  }

ruleAnCycleINdiaidhTime :: Rule
ruleAnCycleINdiaidhTime = Rule
  { name = "an <cycle> i ndiaidh <time>"
  , pattern =
    [ regex "the"
    , dimension TimeGrain
    , regex "(i ndiaidh|tar (Ã©|e)is)"
    , dimension Time
    ]
  , prod = \tokens -> case tokens of
      (_:Token TimeGrain grain:_:Token Time td:_) ->
        tt $ cycleNthAfter False grain 1 td
      _ -> Nothing
  }

ruleDayofmonthOrdinal :: Rule
ruleDayofmonthOrdinal = Rule
  { name = "<day-of-month> (ordinal)"
  , pattern =
    [ Predicate isDOMOrdinal
    ]
  , prod = \tokens -> case tokens of
      (token:_) -> do
        n <- getIntValue token
        tt . mkLatent $ dayOfMonth n
      _ -> Nothing
  }

ruleAnCycleSeo :: Rule
ruleAnCycleSeo = Rule
  { name = "an <cycle> seo"
  , pattern =
    [ regex "an"
    , dimension TimeGrain
    , regex "seo"
    ]
  , prod = \tokens -> case tokens of
      (_:Token TimeGrain grain:_) ->
        tt $ cycleNth grain 0
      _ -> Nothing
  }

ruleAnDayofmonthNonOrdinal :: Rule
ruleAnDayofmonthNonOrdinal = Rule
  { name = "an <day-of-month> (non ordinal)"
  , pattern =
    [ regex "an|na"
    , Predicate isDOMInteger
    ]
  , prod = \tokens -> case tokens of
      (_:token:_) -> do
        v <- getIntValue token
        tt . mkLatent $ dayOfMonth v
      _ -> Nothing
  }

ruleDNamedday :: Rule
ruleDNamedday = Rule
  { name = "dÃ© named-day"
  , pattern =
    [ regex "d(Ã©|e)"
    , Predicate isADayOfWeek
    ]
  , prod = \tokens -> case tokens of
      (_:x:_) -> Just x
      _ -> Nothing
  }

ruleYear :: Rule
ruleYear = Rule
  { name = "year"
  , pattern =
    [ Predicate $ isIntegerBetween 1000 2100
    ]
  , prod = \tokens -> case tokens of
      (token:_) -> do
        v <- getIntValue token
        tt $ year v
      _ -> Nothing
  }

ruleCycleRoimhTime :: Rule
ruleCycleRoimhTime = Rule
  { name = "<cycle> roimh <time>"
  , pattern =
    [ dimension TimeGrain
    , regex "roimhe?"
    , dimension Time
    ]
  , prod = \tokens -> case tokens of
      (Token TimeGrain grain:_:Token Time td:_) ->
        tt $ cycleNthAfter False grain (-1) td
      _ -> Nothing
  }

ruleAbsorptionOfAfterNamedDay :: Rule
ruleAbsorptionOfAfterNamedDay = Rule
  { name = "absorption of , after named day"
  , pattern =
    [ Predicate isADayOfWeek
    , regex ","
    ]
  , prod = \tokens -> case tokens of
      (x:_) -> Just x
      _ -> Nothing
  }

ruleDdmmyyyy :: Rule
ruleDdmmyyyy = Rule
  { name = "dd/mm/yyyy"
  , pattern =
    [ regex "(3[01]|[12]\\d|0?[1-9])[-/](0?[1-9]|1[0-2])[/-](\\d{2,4})"
    ]
  , prod = \tokens -> case tokens of
      (Token RegexMatch (GroupMatch (m1:m2:m3:_)):_) -> do
        y <- parseInt m3
        m <- parseInt m2
        d <- parseInt m1
        tt $ yearMonthDay y m d
      _ -> Nothing
  }

ruleAnNamedday :: Rule
ruleAnNamedday = Rule
  { name = "an named-day"
  , pattern =
    [ regex "an"
    , Predicate isADayOfWeek
    ]
  , prod = \tokens -> case tokens of
      (_:x:_) -> Just x
      _ -> Nothing
  }

ruleDaysOfWeek :: [Rule]
ruleDaysOfWeek = mkRuleDaysOfWeek
  [ ( "Monday"   , "luai?n|lu\\.?"             )
  , ( "Tuesday"  , "mh?(Ã¡|a)irt|m(Ã¡|a)?\\.?"   )
  , ( "Wednesday", "ch?(Ã©|e)adaoin|c(Ã©|e)\\.?" )
  , ( "Thursday" , "d(Ã©|e)ardaoin|d(Ã©|e)?\\.?" )
  , ( "Friday"   , "h?aoine|ao\\.?"            )
  , ( "Saturday" , "sathai?rn|sa\\.?"          )
  , ( "Sunday"   , "domhnai?[cg]h|do\\.?"      )
  ]

ruleMonths :: [Rule]
ruleMonths = mkRuleMonths
  [ ( "January"  , "(mh?(Ã|i) )?(an )?t?ean(Ã¡|a)ir|ean\\.?"     )
  , ( "February" , "(mh?(Ã|i) )?(na )?feabhra|fea\\.?"          )
  , ( "March"    , "(mh?(Ã|i) )?(an )?mh?(Ã¡|a)rta|m(Ã¡|a)r\\.?"  )
  , ( "April"    , "(mh?(Ã|i) )?(an )?t?aibre(Ã¡|a)i?n|abr\\.?"  )
  , ( "May"      , "(mh?(Ã|i) )?(na )?bh?ealtaine|bea\\.?"      )
  , ( "June"     , "(mh?(Ã|i) )?(an )?mh?eith(ea|i)mh|mei\\.?"  )
  , ( "July"     , "(mh?(Ã|i) )?i(Ãº|u)il|i(Ãº|u)i\\.?"           )
  , ( "August"   , "(mh?(Ã|i) )?(na )?l(Ãº|u)nasa|l(Ãº|u)n\\.?"   )
  , ( "September", "(mh?(Ã|i) )?mh?e(Ã¡|a)n f(Ã³|o)mhair|mef?\\.?")
  , ( "October"  , "(mh?(Ã|i) )?(na )?nollai?g|nol\\.?"         )
  , ( "November" , "(mh?(Ã|i) )?(na )?samh(ain|na)|sam\\.?"     )
  , ( "December" , "(mh?(Ã|i) )?(na )?nollai?g|nol\\.?"         )
  ]

ruleCycleINdiaidhTime :: Rule
ruleCycleINdiaidhTime = Rule
  { name = "<cycle> i ndiaidh <time>"
  , pattern =
    [ dimension TimeGrain
    , regex "(i ndiaidh|tar (Ã©|e)is)"
    , dimension Time
    ]
  , prod = \tokens -> case tokens of
      (Token TimeGrain grain:_:Token Time td:_) ->
        tt $ cycleNthAfter False grain 1 td
      _ -> Nothing
  }

ruleDayofmonthordinalNamedmonthYear :: Rule
ruleDayofmonthordinalNamedmonthYear = Rule
  { name = "<day-of-month>(ordinal) <named-month> year"
  , pattern =
    [ Predicate isDOMOrdinal
    , Predicate isAMonth
    , regex "(\\d{2,4})"
    ]
  , prod = \tokens -> case tokens of
      (token:Token Time td:Token RegexMatch (GroupMatch (match:_)):_) -> do
        intVal <- parseInt match
        dom <- intersectDOM td token
        Token Time <$> intersect dom (year intVal)
      _ -> Nothing
  }

rules :: [Rule]
rules =
  [ ruleAbsorptionOfAfterNamedDay
  , ruleAmrach
  , ruleAnCycleDeTime
  , ruleAnCycleINdiaidhTime
  , ruleAnCycleSeo
  , ruleAnDayofmonthNonOrdinal
  , ruleAnDayofmonthOrdinal
  , ruleAnNamedday
  , ruleAnNollaig
  , ruleAnOrdinalCycleDeTime
  , ruleAnOrdinalCycleINdiaidhTime
  , ruleAnnaCycleRoimhTime
  , ruleAnois
  , ruleArAmrach
  , ruleArDate
  , ruleArInn
  , ruleCycleINdiaidhTime
  , ruleCycleInniu
  , ruleCycleRoimhTime
  , ruleCycleShin
  , ruleDNamedday
  , ruleDayofmonthOrdinal
  , ruleDayofmonthordinalNamedmonth
  , ruleDayofmonthordinalNamedmonthYear
  , ruleDdmm
  , ruleDdmmyyyy
  , ruleIGceannCycle
  , ruleInn
  , ruleInniu
  , ruleIntersect
  , ruleIntersectBy
  , ruleLFhileBrde
  , ruleLFhilePdraig
  , ruleLFhileVailintn
  , ruleLNaNaithreacha
  , ruleNollaigNaMban
  , ruleOnANamedday
  , ruleOrdinalCycleDeTime
  , ruleOrdinalCycleINdiaidhTime
  , ruleOrdinalRithe
  , ruleOrdinalRitheYear
  , ruleTimeSeo
  , ruleTimeSeoChaite
  , ruleTimeSeoChugainn
  , ruleYear
  , ruleYearLatent
  , ruleYearLatent2
  , ruleYyyymmdd
  ]
  ++ ruleDaysOfWeek
  ++ ruleMonths


-- Copyright (c) 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the BSD-style license found in the
-- LICENSE file in the root directory of this source tree.

{-# LANGUAGE OverloadedStrings #-}

module Duckling.Time.HU.Corpus
  ( corpus
  ) where

import Data.String
import Prelude

import Duckling.Locale
import Duckling.Resolve
import Duckling.Time.Corpus
import Duckling.TimeGrain.Types hiding (add)
import Duckling.Testing.Types hiding (examples)

corpus :: Corpus
corpus = (testContext {locale = makeLocale HU Nothing}, testOptions, allExamples)

allExamples :: [Example]
allExamples = concat
  [ examples (datetime (2013, 2, 12, 4, 30, 0) Second)
             [ "most"
             , "Ã©pp most"
             , "azonnal"
             , "mostani"
             ]
  , examples (datetime (2013, 2, 12, 0, 0, 0) Day)
             [ "ma"
             , "mÃ¡ma"
             , "Mai nap"
             , "Mai napot"
             , "mai napon"
             , "mai"
             , "mait"
             , "mai napi"
             , "mai napit"
             ]
  , examples (datetime (2013, 2, 13, 0, 0, 0) Day)
             [ "holnap"
             , "holnapi"
             , "holnapit"
             ]
  , examples (datetime (2013, 2, 14, 0, 0, 0) Day)
             [ "holnaputÃ¡n"
             , "holnaputÃ¡ni"
             , "holnaputÃ¡nit"
             ]
  , examples (datetime (2013, 2, 11, 0, 0, 0) Day)
             [ "tegnap"
             , "tegnapi"
             , "tegnapit"
             ]
  , examples (datetime (2013, 2, 10, 0, 0, 0) Day)
             [ "tegnapelÅ‘tt"
             , "tegnapelÅ‘tti"
             , "tegnapelÅ‘ttit"
             ]
  , examples (datetime (2013, 3, 1, 0, 0, 0) Month)
             [ "hÃ³nap vÃ©ge"
             , "a hÃ³nap vÃ©ge"
             , "hÃ³ vÃ©ge"
             , "hÃ³ vÃ©gi"
             , "hÃ³ vÃ©git"
             , "hÃ³ vÃ©gÃ©n"
             ]
  , examples (datetime (2014, 1, 1, 0, 0, 0) Year)
             [ "Ã©v vÃ©ge"
             , "az Ã©v vÃ©ge"
             , "Ã©v vÃ©gi"
             , "Ã©v vÃ©git"
             , "Ã©v vÃ©gÃ©n"
             ]
  , examples (datetime (2013, 2, 18, 0, 0, 0) Day)
             [ "hÃ©tfÅ‘"
             , "hÃ©tfÅ‘n"
             , "hÃ©tfÅ‘t"
             , "hÃ©tfÅ‘i"
             , "hÃ©tfÅ‘it"
             , "hÃ©t."
             , "hÃ©t"
             ]
  , examples (datetime (2013, 2, 19, 0, 0, 0) Day)
             [ "kedd"
             , "kedden"
             , "keddet"
             , "keddi"
             , "keddit"
             ]
  , examples (datetime (2013, 2, 13, 0, 0, 0) Day)
             [ "szerda"
             , "szerdÃ¡n"
             , "szerdÃ¡t"
             , "szerdai"
             , "szerdait"
             , "szer"
             , "szer."
             ]
  , examples (datetime (2013, 2, 14, 0, 0, 0) Day)
             [ "csÃ¼tÃ¶rtÃ¶k"
             , "csÃ¼tÃ¶rtÃ¶kÃ¶n"
             , "csÃ¼tÃ¶rtÃ¶kÃ¶t"
             , "csÃ¼tÃ¶rtÃ¶ki"
             , "csÃ¼tÃ¶rtÃ¶kit"
             , "csÃ¼t"
             , "csÃ¼t."
             ]
  , examples (datetime (2013, 2, 15, 0, 0, 0) Day)
             [ "pÃ©ntek"
             , "pÃ©nteken"
             , "pÃ©nteket"
             , "pÃ©nteki"
             , "pÃ©ntekit"
             , "pÃ©n"
             , "pÃ©n."
             ]
  , examples (datetime (2013, 2, 16, 0, 0, 0) Day)
             [ "szombat"
             , "szombaton"
             , "szombatot"
             , "szombati"
             , "szombatit"
             , "szom"
             , "szom."
             ]
  , examples (datetime (2013, 2, 17, 0, 0, 0) Day)
             [ "vasÃ¡rnap"
             , "vasÃ¡rnapot"
             , "vasÃ¡rnapi"
             , "vasÃ¡rnapit"
             , "vas"
             , "vas."
             ]
  , examples (datetime (2014, 1, 1, 0, 0, 0) Month)
             [ "januÃ¡r"
             , "januÃ¡rban"
             , "januÃ¡ri"
             , "januÃ¡rit"
             , "jan"
             , "jan."
             ]
  , examples (datetime (2013, 2, 1, 0, 0, 0) Month)
             [ "februÃ¡r"
             , "februÃ¡rban"
             , "februÃ¡ri"
             , "februÃ¡rit"
             , "feb"
             , "feb."
             ]
  , examples (datetime (2013, 3, 1, 0, 0, 0) Month)
             [ "mÃ¡rcius"
             , "mÃ¡rciusban"
             , "mÃ¡rciusi"
             , "mÃ¡rciusit"
             , "mÃ¡r"
             , "mÃ¡r."
             , "mÃ¡rc"
             , "mÃ¡rc."
             ]
  , examples (datetime (2013, 4, 1, 0, 0, 0) Month)
             [ "Ã¡prilis"
             , "Ã¡prilisban"
             , "Ã¡prilisi"
             , "Ã¡prilisit"
             , "Ã¡pr"
             , "Ã¡pr."
             ]
  , examples (datetime (2013, 5, 1, 0, 0, 0) Month)
             [ "mÃ¡jus"
             , "mÃ¡jusban"
             , "mÃ¡jusi"
             , "mÃ¡jusit"
             , "mÃ¡j"
             , "mÃ¡j."
             ]
  , examples (datetime (2013, 6, 1, 0, 0, 0) Month)
             [ "jÃºnius"
             , "jÃºniusban"
             , "jÃºniusi"
             , "jÃºniusit"
             , "jÃºn"
             , "jÃºn."
             ]
  , examples (datetime (2013, 7, 1, 0, 0, 0) Month)
             [ "jÃºlius"
             , "jÃºliusban"
             , "jÃºliusi"
             , "jÃºliusit"
             , "jÃºl"
             , "jÃºl."
             ]
  , examples (datetime (2013, 8, 1, 0, 0, 0) Month)
             [ "augusztus"
             , "augusztusban"
             , "augusztusi"
             , "augusztusit"
             , "aug"
             , "aug."
             ]
  , examples (datetime (2013, 9, 1, 0, 0, 0) Month)
             [ "szeptember"
             , "szeptemberben"
             , "szeptemberi"
             , "szeptemberit"
             , "szep"
             , "szep."
             , "szept"
             , "szept."
             ]
  , examples (datetime (2013, 10, 1, 0, 0, 0) Month)
             [ "oktÃ³ber"
             , "oktÃ³berben"
             , "oktÃ³beri"
             , "oktÃ³berit"
             , "okt"
             , "okt."
             ]
  , examples (datetime (2013, 11, 1, 0, 0, 0) Month)
             [ "november"
             , "novemberben"
             , "novemberi"
             , "novemberit"
             , "nov"
             , "nov."
             ]
  , examples (datetime (2013, 12, 1, 0, 0, 0) Month)
             [ "december"
             , "decemberben"
             , "decemberi"
             , "decemberit"
             , "dec"
             , "dec."
             ]
  , examples (datetime (2013, 3, 15, 0, 0, 0) Day)
             [ "mÃ¡rcius 15"
             , "mÃ¡rcius 15."
             , "mÃ¡r 15"
             , "mÃ¡r. 15"
             , "mÃ¡rc 15"
             , "mÃ¡rc. 15"
             ]
  , examples (datetime (2013, 3, 1, 0, 0, 0) Day)
            [ "mÃ¡rcius 1-Ã©n"
            , "mÃ¡rcius 1-jÃ©n"
            , "mÃ¡rcius 1-je"
            , "mÃ¡rcius 1-jei"
            , "mÃ¡rcius 1-i"
            , "mÃ¡rcius 1Ã©n"
            , "mÃ¡rcius 1je"
            , "mÃ¡rcius 1jei"
            , "mÃ¡rcius 1i"
            ]
  , examples (datetime (2013, 3, 2, 0, 0, 0) Day)
            [ "mÃ¡rcius 2-Ã¡n"
            , "mÃ¡rcius 2-ai"
            , "mÃ¡rcius 2-a"
            , "mÃ¡rcius 2Ã¡n"
            , "mÃ¡rcius 2ai"
            , "mÃ¡rcius 2a"
            ]
  , examples (datetime (2013, 3, 4, 0, 0, 0) Day)
            [ "mÃ¡rcius 4-e"
            , "mÃ¡rcius 4e"
            ]
  , examples (datetime (2013, 3, 7, 0, 0, 0) Day)
            [ "mÃ¡rcius 7-ei"
            , "mÃ¡rcius 7ei"
            ]
  , examples (datetime (2013, 3, 15, 0, 0, 0) Day)
            [ "mÃ¡rcius 15-Ã©n"
            , "mÃ¡rcius 15-ei"
            , "mÃ¡rcius 15-i"
            , "mÃ¡rcius 15Ã©n"
            , "mÃ¡rcius 15e"
            , "mÃ¡rcius 15ei"
            ]
  , examples (datetime (2013, 3, 1, 0, 0, 0) Month)
             [ "kÃ¶vetkezÅ‘ hÃ³nap"
             , "jÃ¶vÅ‘ hÃ³nap"
             ]
  , examples (datetime (2012, 1, 1, 0, 0, 0) Year)
             [ "elÅ‘zÅ‘ Ã©v"
             , "mÃºlt Ã©v"
             ]
  , examples (datetime (2013, 2, 21, 0, 0, 0) Day)
             [ "jÃ¶vÅ‘ csÃ¼tÃ¶rtÃ¶k"
             ]
  , examples (datetime (2013, 2, 12, 15, 20, 0) Minute)
             [ "15:20"
             ]
  , examples (datetime (2013, 2, 12, 8, 20, 0) Minute)
             [ "08:20"
             , "8:20"
             ]
  , examples (datetime (2013, 2, 12, 15, 20, 44) Second)
             [ "15:20:44"
             ]
  , examples (datetime (2013, 2, 12, 8, 20, 44) Second)
             [ "08:20:44"
             , "8:20:44"
             ]
  , examples (datetime (2013, 2, 12, 11, 0, 0) Hour)
             [ "de 11"
             , "de. 11"
             , "dÃ©lelÅ‘tt 11"
             ]
  , examples (datetime (2013, 2, 12, 23, 0, 0) Hour)
             [ "du 11"
             , "du. 11"
             , "dÃ©lutÃ¡n 11"
             ]
  , examples (datetime (2013, 2, 13, 23, 0, 0) Hour)
             [ "szerda du 11"
             , "szerda du. 11"
             , "szerda dÃ©lutÃ¡n 11"
             ]
  , examples (datetime (2013, 2, 20, 23, 0, 0) Hour)
             [ "jÃ¶vÅ‘ szerda du 11"
             , "jÃ¶vÅ‘ szerda du. 11"
             , "jÃ¶vÅ‘ szerda dÃ©lutÃ¡n 11"
             ]
  , examples (datetime (2013, 8, 20, 0, 0, 0) Day)
             [ "2013.08.20"
             , "2013 . 08 . 20"
             , "2013-08-20"
             , "2013 - 08 - 20"
             ]
  , examples (datetime (2013, 8, 20, 11, 45, 0) Minute)
             [ "2013.08.20 11:45"
             ]
  , examples (datetime (2013, 8, 20, 17, 0, 0) Hour)
             [ "2013.08.20 dÃ©lutÃ¡n 5"
             ]
  , examples (datetime (2013, 8, 20, 0, 0, 0) Day)
             [ "08.20"
             , "08 . 20"
             , "08-20"
             , "08 - 20"
             ]
  , examples (datetimeInterval ((2013, 2, 12, 6, 0, 0), (2013, 2, 12, 10, 0, 0)) Hour)
             [ "ma reggel"
             , "reggel"
             , "ma reggeli"
             , "reggeli"
             , "ma reggelit"
             , "reggelit"
             ]
  , examples (datetimeInterval ((2013, 2, 12, 8, 0, 0), (2013, 2, 12, 12, 0, 0)) Hour)
             [ "dÃ©lelÅ‘tt"
             , "dÃ©lelÅ‘tti"
             , "dÃ©lelÅ‘ttit"
             ]
  , examples (datetimeInterval ((2013, 2, 12, 12, 0, 0), (2013, 2, 12, 13, 0, 0)) Hour)
             [ "dÃ©lben"
             , "dÃ©li"
             , "dÃ©lit"
             ]
  , examples (datetimeInterval ((2013, 2, 13, 8, 0, 0), (2013, 2, 13, 12, 0, 0)) Hour)
             [ "holnap dÃ©lelÅ‘tt"
             ]
  , examples (datetimeInterval ((2013, 2, 11, 12, 0, 0), (2013, 2, 11, 13, 0, 0)) Hour)
             [ "tegnap dÃ©lben"
             ]
  , examples (datetimeInterval ((2013, 2, 12, 12, 0, 0), (2013, 2, 12, 18, 0, 0)) Hour)
             [ "ma dÃ©lutÃ¡n"
             , "dÃ©lutÃ¡n"
             , "dÃ©lutÃ¡ni"
             , "dÃ©lutÃ¡nit"
             ]
  , examples (datetimeInterval ((2013, 2, 12, 16, 0, 0), (2013, 2, 12, 20, 0, 0)) Hour)
             [ "ma este"
             , "este"
             , "esti"
             , "estit"
             ]
  , examples (datetimeInterval ((2013, 2, 12, 20, 0, 0), (2013, 2, 12, 23, 0, 0)) Hour)
             [ "ma Ã©jszaka"
             , "Ã©jszaka"
             , "Ã©jszakai"
             , "Ã©jszakait"
             ]
  , examples (datetimeInterval ((2013, 6, 21, 0, 0, 0), (2013, 9, 24, 0, 0, 0)) Day)
             [ "nyÃ¡r"
             , "nyÃ¡ri"
             , "nyÃ¡rit"
             , "nyÃ¡ron"
             ]
   , examples (datetimeInterval ((2013, 9, 23, 0, 0, 0), (2013, 12, 22, 0, 0, 0)) Day)
             [ "Å‘sz"
             , "Å‘szi"
             , "Å‘szit"
             , "Å‘sszel"
             ]
  , examples (datetimeInterval ((2012, 12, 21, 0, 0, 0), (2013, 3, 21, 0, 0, 0)) Day)
             [ "tÃ©l"
             , "tÃ©li"
             , "tÃ©lit"
             , "tÃ©len"
             ]
    , examples (datetimeInterval ((2013, 3, 20, 0, 0, 0), (2013, 6, 22, 0, 0, 0)) Day)
             [ "tavasz"
             , "tavaszi"
             , "tavaszit"
             , "tavasszal"
             ]
  ]


-- Copyright (c) 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the BSD-style license found in the
-- LICENSE file in the root directory of this source tree.

{-# LANGUAGE GADTs #-}
{-# LANGUAGE NoRebindableSyntax #-}
{-# LANGUAGE OverloadedStrings #-}

module Duckling.Time.HU.Rules
  ( rules ) where

import Data.Maybe
import Prelude
import qualified Data.Text as Text

import Duckling.Dimensions.Types
import Duckling.Numeral.Helpers (parseInt)
import Duckling.Regex.Types
import Duckling.Types
import Duckling.Time.Helpers
import qualified Duckling.Time.Types as TTime
import qualified Duckling.TimeGrain.Types as TG

ruleIntersect :: Rule
ruleIntersect = Rule
  { name = "intersect"
  , pattern =
    [ Predicate isNotLatent
    , Predicate isNotLatent
    ]
  , prod = \tokens -> case tokens of
      (Token Time td1:Token Time td2:_) -> Token Time <$> intersect td1 td2
      _ -> Nothing
  }

ruleInstants :: [Rule]
ruleInstants = mkRuleInstants
  [ ("right now",            TG.Second, 0 , "mostani(t)?|((\x00E9pp )?most)|azonnal"                      )
  , ("today",                TG.Day,    0 , "m(Ã¡|a)(i( nap(o(t|n)|it?)?|t)?|ma)?"                         )
  , ("tomorrow",             TG.Day,    1 , "holnap(i(t)?)?"                                              )
  , ("day after tomorrow",   TG.Day,    2 , "holnaput\x00E1n(i(t)?)?"                                     )
  , ("yesterday",            TG.Day,    -1, "tegnap(i(t)?)?"                                              )
  , ("day before yesterday", TG.Day,    -2, "tegnapel\x0151tt(i(t)?)?"                                    )
  , ("end of month",         TG.Month,  1 , "(a )?h\x00F3nap v\x00E9ge|h\x00F3 v\x00E9g(e|i(t)?|\x00E9n)" )
  , ("end of year",          TG.Year,   1 , "(az )?\x00E9v v\x00E9g(e|i(t)?|\x00E9n)"                     )
  ]

ruleDaysOfWeek :: [Rule]
ruleDaysOfWeek = mkRuleDaysOfWeek
  [ ( "Monday"   , "h\x00E9tf\x0151(n|t|i(t)?)?|h\x00E9t\\.?"                   )
  , ( "Tuesday"  , "kedd(en|et|i(t)?)?"                                         )
  , ( "Wednesday", "szerda(i(t)?)?|szerdÃ¡(n|t)|szer\\.?"                        )
  , ( "Thursday" , "cs\x00FCt\x00F6rt\x00F6k(\x00F6(n|t)|i(t)?)?|cs\x00FCt\\.?" )
  , ( "Friday"   , "p\x00E9ntek(e(n|t)|i(t)?)?|p\x00E9n\\.?"                    )
  , ( "Saturday" , "szombat(o(n|t)|i(t)?)?|szom\\.?"                            )
  , ( "Sunday"   , "vas\x00E1rnap(ot|i(t)?)?|vas\\.?"                           )
  ]

ruleMonths :: [Rule]
ruleMonths = mkRuleMonths
  [ ( "January"  , "janu\x00E1r(ban|i(t)?)?|jan\\.?"         )
  , ( "February" , "febru\x00E1r(ban|i(t)?)?|febr?\\.?"      )
  , ( "March"    , "m\x00E1rcius(ban|i(t)?)?|m\x00E1rc?\\.?" )
  , ( "April"    , "\x00E1prilis(ban|i(t)?)?|\x00E1pr\\.?"   )
  , ( "May"      , "m\x00E1jus(ban|i(t)?)?|m\x00E1j\\.?"     )
  , ( "June"     , "j\x00FAnius(ban|i(t)?)?|j\x00FAn\\.?"    )
  , ( "July"     , "j\x00FAlius(ban|i(t)?)?|j\x00FAl\\.?"    )
  , ( "August"   , "augusztus(ban|i(t)?)?|aug\\.?"           )
  , ( "September", "szeptember(ben|i(t)?)?|szept?\\.?"       )
  , ( "October"  , "oktÃ³ber(ben|i(t)?)?|okt\\.?"             )
  , ( "November" , "november(ben|i(t)?)?|nov\\.?"            )
  , ( "December" , "december(ben|i(t)?)?|dec\\.?"            )
  ]

ruleMonthDOMNumeral :: Rule
ruleMonthDOMNumeral = Rule
  { name = "<named-month> <day-of-month> (non ordinal)"
  , pattern =
    [ Predicate isAMonth
    , Predicate isDOMInteger
    ]
  , prod = \tokens -> case tokens of
      (Token Time td:token:_) -> Token Time <$> intersectDOM td token
      _ -> Nothing
  }

ruleMonthDOMNumeralSuffix :: Rule
ruleMonthDOMNumeralSuffix = Rule
  { name = "<named-month> <day-of-month> (non ordinal)"
  , pattern =
    [ Predicate isAMonth
    , Predicate isDOMInteger
    , regex "(-?(jei|jÃ©n|Ã¡n|Ã©n|ai|ei|je|ji|a|e|i))"
    ]
  , prod = \tokens -> case tokens of
      (Token Time td:token:_) -> Token Time <$> intersectDOM td token
      _ -> Nothing
  }

ruleMonthDOMOrdinal :: Rule
ruleMonthDOMOrdinal = Rule
  { name = "<named-month> <day-of-month> (ordinal)"
  , pattern =
    [ Predicate isAMonth
    , Predicate isDOMOrdinal
    ]
  , prod = \tokens -> case tokens of
      (Token Time td:token:_) -> Token Time <$> intersectDOM td token
      _ -> Nothing
  }

ruleCycleThisLastNext :: Rule
ruleCycleThisLastNext = Rule
  { name = "this|last|next <cycle>"
  , pattern =
    [ regex "(most|el\x0151z\x0151|m\x00FAlt|k\x00F6vetkez\x0151|j\x00F6v\x0151)"
    , dimension TimeGrain
    ]
  , prod = \tokens -> case tokens of
      (Token RegexMatch (GroupMatch (match:_)):Token TimeGrain grain:_) ->
        case Text.toLower match of
          "most"                -> tt $ cycleNth grain 0
          "el\x0151z\x0151"     -> tt . cycleNth grain $ - 1
          "m\x00FAlt"           -> tt . cycleNth grain $ - 1
          "k\x00F6vetkez\x0151" -> tt $ cycleNth grain 1
          "j\x00F6v\x0151"      -> tt $ cycleNth grain 1
          _ -> Nothing
      _ -> Nothing
  }

ruleNextDOW :: Rule
ruleNextDOW = Rule
  { name = "next <day-of-week>"
  , pattern =
    [ regex "j\x00F6v\x0151"
    , Predicate isADayOfWeek
    ]
  , prod = \tokens -> case tokens of
      (_:Token Time td:_) -> tt $ predNth 1 True td
      _ -> Nothing
  }

ruleHHMM :: Rule
ruleHHMM = Rule
  { name = "hh:mm"
  , pattern =
    [ regex "((?:[01]?\\d)|(?:2[0-3]))[:.]([0-5]\\d)"
    ]
  , prod = \tokens -> case tokens of
      (Token RegexMatch (GroupMatch (hh:mm:_)):_) -> do
        h <- parseInt hh
        m <- parseInt mm
        tt $ hourMinute True h m
      _ -> Nothing
  }

ruleHHMMSS :: Rule
ruleHHMMSS = Rule
  { name = "hh:mm:ss"
  , pattern =
    [ regex "((?:[01]?\\d)|(?:2[0-3]))[:.]([0-5]\\d)[:.]([0-5]\\d)"
    ]
  , prod = \tokens -> case tokens of
      (Token RegexMatch (GroupMatch (hh:mm:ss:_)):_) -> do
        h <- parseInt hh
        m <- parseInt mm
        s <- parseInt ss
        tt $ hourMinuteSecond True h m s
      _ -> Nothing
  }

ruleTODLatent :: Rule
ruleTODLatent = Rule
  { name = "time-of-day (latent)"
  , pattern =
    [ Predicate $ isIntegerBetween 0 23
    ]
  , prod = \tokens -> case tokens of
      (token:_) -> do
        n <- getIntValue token
        tt . mkLatent $ hour True n
      _ -> Nothing
  }

ruleTODAM :: Rule
ruleTODAM = Rule
  { name = "am <time-of-day>"
  , pattern =
    [ regex "(de\\.?|d\x00E9lel\x0151tt)"
    , Predicate isATimeOfDay
    ]
  , prod = \tokens -> case tokens of
      (_:Token Time td:_) -> tt $ timeOfDayAMPM True td
      _ -> Nothing
  }

ruleTODPM :: Rule
ruleTODPM = Rule
  { name = "pm <time-of-day>"
  , pattern =
    [ regex "(du\\.?|d\x00E9lut\x00E1n)"
    , Predicate isATimeOfDay
    ]
  , prod = \tokens -> case tokens of
      (_:Token Time td:_) -> tt $ timeOfDayAMPM False td
      _ -> Nothing
  }

ruleYYYYMMDD :: Rule
ruleYYYYMMDD = Rule
  { name = "yyyy.mm.dd"
  , pattern =
    [ regex "(\\d{2,4})\\s?[-\\.]\\s?(0?[1-9]|1[0-2])\\s?[-\\.]\\s?(3[01]|[12]\\d|0?[1-9])"
    ]
  , prod = \tokens -> case tokens of
      (Token RegexMatch (GroupMatch (yy:mm:dd:_)):_) -> do
        y <- parseInt yy
        m <- parseInt mm
        d <- parseInt dd
        tt $ yearMonthDay y m d
      _ -> Nothing
  }

ruleMMDD :: Rule
ruleMMDD = Rule
  { name = "mm.dd"
  , pattern =
    [ regex "(0?[1-9]|1[0-2])\\s?[-\\.]\\s?(3[01]|[12]\\d|0?[1-9])"
    ]
  , prod = \tokens -> case tokens of
      (Token RegexMatch (GroupMatch (mm:dd:_)):_) -> do
        m <- parseInt mm
        d <- parseInt dd
        tt $ monthDay m d
      _ -> Nothing
  }

rulePartOfDays :: Rule
rulePartOfDays = Rule
  { name = "part of days"
  , pattern =
    [ regex "(reggel(i(t)?)?|d\x00E9lel\x0151tt(i(t)?)?|d\x00E9lben|d\x00E9li(t)?|d\x00E9lut\x00E1n(i(t)?)?|est(e|i(t)?)|\x00E9jszaka(i(t)?)?)"
    ]
  , prod = \tokens -> case tokens of
      (Token RegexMatch (GroupMatch (match:_)):_) -> do
        let (start, end) = case Text.toLower match of
              "reggel"               -> (hour False 6, hour False 10)
              "reggeli"              -> (hour False 6, hour False 10)
              "reggelit"             -> (hour False 6, hour False 10)
              "d\x00E9lel\x0151tt"   -> (hour False 08, hour False 12)
              "d\x00E9lel\x0151tti"  -> (hour False 08, hour False 12)
              "d\x00E9lel\x0151ttit" -> (hour False 08, hour False 12)
              "d\x00E9lben"          -> (hour False 12, hour False 13)
              "d\x00E9li"            -> (hour False 12, hour False 13)
              "d\x00E9lit"           -> (hour False 12, hour False 13)
              "d\x00E9lut\x00E1n"    -> (hour False 12, hour False 18)
              "d\x00E9lut\x00E1ni"   -> (hour False 12, hour False 18)
              "d\x00E9lut\x00E1nit"  -> (hour False 12, hour False 18)
              "este"                 -> (hour False 16, hour False 20)
              "esti"                 -> (hour False 16, hour False 20)
              "estit"                -> (hour False 16, hour False 20)
              _                      -> (hour False 20, hour False 23)
        td <- interval TTime.Open start end
        tt . partOfDay $ td
      _ -> Nothing
  }

-- Since part of days are latent, general time intersection is blocked
ruleTimePOD :: Rule
ruleTimePOD = Rule
  { name = "<time> <part-of-day>"
  , pattern =
    [ dimension Time
    , Predicate isAPartOfDay
    ]
  , prod = \tokens -> case tokens of
      (Token Time td:Token Time pod:_) -> Token Time <$> intersect pod td
      _ -> Nothing
  }

ruleSeasons :: Rule
ruleSeasons = Rule
  { name = "seasons"
  , pattern =
    [ regex "(ny\x00E1r(i(t)?|on)?|\x0151sz(i(t)?)?|\x0151sszel|t\x00E9l(i(t)?|en)?|tavasz(i(t)?)?|tavasszal)"
    ]
  , prod = \tokens -> case tokens of
      (Token RegexMatch (GroupMatch (match:_)):_) -> do
        start <- case Text.toLower match of
          "ny\x00E1r"      -> Just $ monthDay 6 21
          "ny\x00E1ri"     -> Just $ monthDay 6 21
          "ny\x00E1rit"    -> Just $ monthDay 6 21
          "ny\x00E1ron"    -> Just $ monthDay 6 21
          "\x0151sz"       -> Just $ monthDay 9 23
          "\x0151szi"      -> Just $ monthDay 9 23
          "\x0151szit"     -> Just $ monthDay 9 23
          "\x0151sszel"    -> Just $ monthDay 9 23
          "t\x00E9l"       -> Just $ monthDay 12 21
          "t\x00E9li"      -> Just $ monthDay 12 21
          "t\x00E9lit"     -> Just $ monthDay 12 21
          "t\x00E9len"     -> Just $ monthDay 12 21
          "tavasz"         -> Just $ monthDay 3 20
          "tavaszi"        -> Just $ monthDay 3 20
          "tavaszit"       -> Just $ monthDay 3 20
          "tavasszal"      -> Just $ monthDay 3 20
          _ -> Nothing
        end <- case Text.toLower match of
          "ny\x00E1r"      -> Just $ monthDay 9 23
          "ny\x00E1ri"     -> Just $ monthDay 9 23
          "ny\x00E1rit"    -> Just $ monthDay 9 23
          "ny\x00E1ron"    -> Just $ monthDay 9 23
          "\x0151sz"       -> Just $ monthDay 12 21
          "\x0151szi"      -> Just $ monthDay 12 21
          "\x0151szit"     -> Just $ monthDay 12 21
          "\x0151sszel"    -> Just $ monthDay 12 21
          "t\x00E9l"       -> Just $ monthDay 3 20
          "t\x00E9li"      -> Just $ monthDay 3 20
          "t\x00E9lit"     -> Just $ monthDay 3 20
          "t\x00E9len"     -> Just $ monthDay 3 20
          "tavasz"         -> Just $ monthDay 6 21
          "tavaszi"        -> Just $ monthDay 6 21
          "tavaszit"       -> Just $ monthDay 6 21
          "tavasszal"      -> Just $ monthDay 6 21
          _ -> Nothing
        Token Time <$> interval TTime.Open start end
      _ -> Nothing

  }

rules :: [Rule]
rules =
  [ ruleIntersect
  , ruleMonthDOMNumeral
  , ruleMonthDOMNumeralSuffix
  , ruleMonthDOMOrdinal
  , ruleCycleThisLastNext
  , ruleNextDOW
  , ruleHHMM
  , ruleHHMMSS
  , ruleTODLatent
  , ruleTODAM
  , ruleTODPM
  , ruleYYYYMMDD
  , ruleMMDD
  , rulePartOfDays
  , ruleTimePOD
  , ruleSeasons
  ]
  ++ ruleInstants
  ++ ruleDaysOfWeek
  ++ ruleMonths


-- Copyright (c) 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the BSD-style license found in the
-- LICENSE file in the root directory of this source tree.

{-# LANGUAGE OverloadedStrings #-}

module Duckling.Time.IT.Corpus
  ( corpus
  , negativeCorpus
  ) where

import Data.String
import Prelude

import Duckling.Locale
import Duckling.Resolve
import Duckling.Time.Corpus
import Duckling.Time.Types hiding (Month)
import Duckling.TimeGrain.Types hiding (add)
import Duckling.Testing.Types hiding (examples)

corpus :: Corpus
corpus = (testContext {locale = makeLocale IT Nothing}, testOptions, allExamples)

negativeCorpus :: NegativeCorpus
negativeCorpus = (testContext {locale = makeLocale IT Nothing}, testOptions, examples)
  where
    examples =
      [ "ma"
      , "3 20"
      ]

allExamples :: [Example]
allExamples = concat
  [ examples (datetime (2013, 2, 12, 4, 30, 0) Second)
             [ "subito"
             , "immediatamente"
             , "in questo momento"
             , "ora"
             , "adesso"
             ]
  , examples (datetime (2013, 2, 12, 0, 0, 0) Day)
             [ "di oggi"
             , "oggi"
             , "in giornata"
             ]
  , examples (datetime (2013, 2, 11, 0, 0, 0) Day)
             [ "ieri"
             ]
  , examples (datetime (2013, 2, 13, 0, 0, 0) Day)
             [ "domani"
             ]
  , examples (datetime (2013, 2, 14, 0, 0, 0) Day)
             [ "Il giorno dopo domani"
             , "dopodomani"
             ]
  , examples (datetime (2013, 2, 18, 0, 0, 0) Day)
             [ "LunedÃ¬ 18 febbraio"
             ]
  , examples (datetime (2013, 2, 19, 0, 0, 0) Day)
             [ "martedÃ¬"
             , "MartedÃ¬ 19"
             , "mar 19"
             , "il 19"
             ]
  , examples (datetime (2013, 2, 10, 0, 0, 0) Day)
             [ "l'altro ieri"
             , "altroieri"
             ]
  , examples (datetime (2013, 2, 18, 0, 0, 0) Day)
             [ "lunedi"
             , "lun"
             ]
  , examples (datetime (2013, 2, 18, 0, 0, 0) Day)
             [ "lunedi 18 febbraio"
             ]
  , examples (datetime (2013, 2, 19, 0, 0, 0) Day)
             [ "MartedÃ¬"
             , "Martedi"
             , "mar"
             ]
  , examples (datetime (2013, 2, 13, 0, 0, 0) Day)
             [ "MercoledÃ¬"
             , "mer"
             , "mer."
             ]
  , examples (datetime (2013, 2, 13, 0, 0, 0) Day)
             [ "mercoledi 13 feb"
             , "il 13 febbraio"
             ]
  , examples (datetime (2013, 2, 13, 0, 0, 0) Day)
             [ "il 13 febbraio 2013"
             ]
  , examples (datetime (2013, 2, 14, 0, 0, 0) Day)
             [ "giovedi"
             , "giovedÃ¬"
             , "gio"
             ]
  , examples (datetime (2013, 2, 15, 0, 0, 0) Day)
             [ "venerdi"
             , "venerdÃ¬"
             , "ven"
             ]
  , examples (datetime (2013, 2, 16, 0, 0, 0) Day)
             [ "sabato"
             , "sab"
             , "sab."
             ]
  , examples (datetime (2013, 2, 17, 0, 0, 0) Day)
             [ "domenica"
             , "dom"
             , "dom."
             ]
   , examples (datetime (2013, 1, 1, 0, 0, 0) Month)
              [ "gennaio 2013"
              , "genn 2013"
              , "genn. 2013"
              ]
  , examples (datetime (2013, 12, 1, 0, 0, 0) Month)
              [ "dicembre 2013"
              , "dic 2013"
              , "dic. 2013"
              ]
  , examples (datetime (2013, 2, 10, 0, 0, 0) Day)
             [ "domenica 10 febbraio"
             ]
  , examples (datetime (2013, 3, 1, 0, 0, 0) Day)
             [ "il 1 marzo"
             , "primo marzo"
             , "primo di marzo"
             , "il 1Âº marzo"
             ]
  , examples (datetimeOpenInterval Before (2013, 3, 1, 0, 0, 0) Month)
             [ "prima di marzo"
             ]
  , examples (datetime (2013, 3, 15, 0, 0, 0) Day)
             [ "le idi di marzo"
             , "idi di marzo"
             ]
  , examples (datetime (2015, 3, 3, 0, 0, 0) Day)
             [ "3 marzo 2015"
             , "3/3/2015"
             , "3/3/15"
             , "2015-3-3"
             , "2015-03-03"
             ]
  , examples (datetime (2013, 2, 15, 0, 0, 0) Day)
             [ "il 15 febbraio"
             , "15/2"
             , "il 15/02"
             ]
  , examples (datetime (1974, 10, 31, 0, 0, 0) Day)
             [ "31/10/1974"
             , "31/10/74"
             ]
  , examples (datetime (2013, 2, 5, 0, 0, 0) Day)
             [ "martedÃ¬ scorso"
             ]
  , examples (datetime (2013, 2, 19, 0, 0, 0) Day)
             [ "martedÃ¬ prossimo"
             , "il martedÃ¬ dopo"
             ]
  , examples (datetime (2013, 2, 20, 0, 0, 0) Day)
             [ "mercoledÃ¬ prossimo"
             ]
  , examples (datetime (2014, 10, 0, 0, 0, 0) Month)
             [ "ottobre 2014"
             ]
  , examples (datetime (2013, 2, 12, 3, 0, 0) Hour)
             [ "l'ultima ora"
             , "nell'ultima ora"
             ]
  , examples (datetime (2013, 2, 11, 0, 0, 0) Week)
             [ "questa settimana"
             ]
  , examples (datetime (2013, 2, 4, 0, 0, 0) Week)
             [ "la settimana scorsa"
             , "la scorsa settimana"
             , "nella scorsa settimana"
             , "della settimana scorsa"
             ]
  , examples (datetime (2013, 2, 18, 0, 0, 0) Week)
             [ "la settimana prossima"
             , "la prossima settimana"
             , "nella prossima settimana"
             , "settimana prossima"
             , "prossima settimana"
             ]
  , examples (datetime (2013, 1, 0, 0, 0, 0) Month)
             [ "il mese scorso"
             , "nel mese scorso"
             , "nel mese passato"
             , "lo scorso mese"
             , "dello scorso mese"
             ]
  , examples (datetime (2013, 3, 0, 0, 0, 0) Month)
             [ "il mese prossimo"
             , "il prossimo mese"
             ]
  , examples (datetime (2013, 1, 1, 0, 0, 0) Quarter)
             [ "questo trimestre"
             ]
  , examples (datetime (2013, 4, 1, 0, 0, 0) Quarter)
             [ "il prossimo trimestre"
             , "nel prossimo trimestre"
             ]
  , examples (datetime (2013, 7, 1, 0, 0, 0) Quarter)
             [ "terzo trimestre"
             , "il terzo trimestre"
             ]
  , examples (datetime (2018, 10, 1, 0, 0, 0) Quarter)
             [ "quarto trimestre 2018"
             , "il quarto trimestre 2018"
             , "del quarto trimestre 2018"
             ]
  , examples (datetime (2012, 0, 0, 0, 0, 0) Year)
             [ "l'anno scorso"
             ]
  , examples (datetime (2013, 0, 0, 0, 0, 0) Year)
             [ "quest'anno"
             ]
  , examples (datetime (2014, 0, 0, 0, 0, 0) Year)
             [ "il prossimo anno"
             ]
  , examples (datetime (2013, 2, 10, 0, 0, 0) Day)
             [ "ultima domenica"
             ]
  , examples (datetime (2013, 2, 11, 0, 0, 0) Day)
             [ "lunedÃ¬ di questa settimana"
             ]
  , examples (datetime (2013, 2, 12, 0, 0, 0) Day)
             [ "martedÃ¬ di questa settimana"
             ]
  , examples (datetime (2013, 2, 13, 0, 0, 0) Day)
             [ "mercoledÃ¬ di questa settimana"
             ]
  , examples (datetime (2013, 2, 14, 17, 0, 0) Hour)
             [ "dopo domani alle 17"
             , "dopodomani alle 5 del pomeriggio"
             ]
  , examples (datetime (2013, 3, 25, 0, 0, 0) Day)
             [ "ultimo lunedÃ¬ di marzo"
             ]
  , examples (datetime (2014, 3, 30, 0, 0, 0) Day)
             [ "ultima domenica di marzo 2014"
             ]
  , examples (datetime (2013, 10, 3, 0, 0, 0) Day)
             [ "il terzo giorno di ottobre"
             ]
  , examples (datetime (2014, 10, 6, 0, 0, 0) Week)
             [ "prima settimana di ottobre 2014"
             ]
  , examples (datetime (2013, 10, 7, 0, 0, 0) Week)
             [ "la settimana del 6 ottobre"
             , "la settimana del 7 ott"
             ]
  , examples (datetimeInterval ((2013, 2, 15, 18, 0, 0), (2013, 2, 18, 0, 0, 0)) Hour)
             [ "il we del 15 febbraio"
             ]
  , examples (datetimeInterval ((2013, 4, 12, 18, 0, 0), (2013, 4, 15, 0, 0, 0)) Hour)
             [ "il week-end del 10 aprile"
             ]
  , examples (datetime (2015, 10, 31, 0, 0, 0) Day)
             [ "l'ultimo giorno di ottobre 2015"
             , "l'ultimo giorno dell'ottobre 2015"
             ]
  , examples (datetime (2014, 9, 22, 0, 0, 0) Week)
             [ "l'ultima settimana di settembre 2014"
             ]
  , examples (datetime (2013, 2, 12, 5, 30, 0) Minute)
             [ "tra un'ora"
             , "tra 1 ora"
             ]
  , examples (datetime (2013, 2, 12, 4, 45, 0) Second)
             [ "tra un quarto d'ora"
             ]
  , examples (datetime (2013, 2, 12, 5, 0, 0) Second)
             [ "tra mezz'ora"
             ]
  , examples (datetime (2013, 2, 12, 5, 15, 0) Second)
             [ "tra tre quarti d'ora"
             ]
  , examples (datetime (2013, 10, 1, 0, 0, 0) Day)
             [ "primo martedÃ¬ di ottobre"
             , "primo martedÃ¬ in ottobre"
             , "1Â° martedÃ¬ del mese di ottobre"
             , "1Âº martedÃ¬ del mese di ottobre"
             ]
  , examples (datetime (2014, 9, 16, 0, 0, 0) Day)
             [ "terzo martedÃ¬ di settembre 2014"
             ]
  , examples (datetime (2014, 10, 1, 0, 0, 0) Day)
             [ "primo mercoledÃ¬ di ottobre 2014"
             ]
  , examples (datetime (2014, 10, 8, 0, 0, 0) Day)
             [ "secondo mercoledÃ¬ di ottobre 2014"
             ]
  , examples (datetime (2015, 1, 13, 0, 0, 0) Day)
             [ "terzo martedÃ¬ dopo natale 2014"
             ]
  , examples (datetime (2016, 1, 0, 0, 0, 0) Month)
             [ "il mese dopo natale 2015"
             ]
  , examples (datetime (2013, 2, 12, 15, 0, 0) Hour)
             [ "alle 3 di pomeriggio"
             , "le tre di pomeriggio"
             , "alle 3 del pomeriggio"
             , "le tre del pomeriggio"
             ]
  , examples (datetime (2013, 2, 12, 15, 0, 0) Hour)
             [ "circa alle 3 del pomeriggio"
             ]
  , examples (datetime (2013, 2, 12, 15, 0, 0) Hour)
             [ "per le 15"
             , "verso le 15"
             ]
  , examples (datetime (2013, 2, 13, 3, 0, 0) Minute)
             [ "3:00"
             , "03:00"
             ]
  , examples (datetime (2013, 2, 12, 15, 15, 0) Minute)
             [ "15:15"
             ]
  , examples (datetime (2013, 2, 12, 15, 15, 0) Minute)
             [ "3:15 di pomeriggio"
             , "3:15 del pomeriggio"
             , "3 e un quarto di pomeriggio"
             , "tre e un quarto di pomeriggio"
             ]
  , examples (datetime (2013, 2, 12, 15, 20, 0) Minute)
             [ "alle tre e venti di pomeriggio"
             , "alle tre e venti del pomeriggio"
             , "3:20 di pomeriggio"
             , "3:20 del pomeriggio"
             , "15:20 del pomeriggio"
             ]
  , examples (datetime (2013, 2, 13, 3, 20, 0) Minute)
             [ "alle tre e venti"
             , "tre e 20"
             , "3 e 20"
             , "3:20"
             , "alle 3 20"
             ]
  , examples (datetime (2013, 2, 12, 15, 30, 0) Minute)
             [ "15:30"
             ]
  , examples (datetime (2013, 2, 12, 11, 45, 0) Minute)
             [ "a mezzogiorno meno un quarto"
             , "mezzogiorno meno un quarto"
             , "un quarto a mezzogiorno"
             , "11:45 del mattino"
             ]
  , examples (datetime (2013, 2, 13, 3, 0, 0) Hour)
             [ "alle 3 del mattino"
             ]
  , examples (datetime (2013, 9, 20, 19, 30, 0) Minute)
             [ "alle 19:30 di venerdÃ¬ 20 settembre"
             , "alle 19:30 venerdÃ¬ 20 settembre"
             , "venerdÃ¬ 20 settembre alle 19:30"
             , "il 20 settembre alle 19:30"
             ]
  , examples (datetimeInterval ((2013, 2, 15, 18, 0, 0), (2013, 2, 18, 0, 0, 0)) Hour)
             [ "questo week-end"
             , "questo fine settimana"
             , "questo finesettimana"
             ]
  , examples (datetimeInterval ((2013, 2, 18, 4, 0, 0), (2013, 2, 18, 12, 0, 0)) Hour)
             [ "lunedi mattina"
             ]
  , examples (datetimeInterval ((2013, 2, 15, 4, 0, 0), (2013, 2, 15, 12, 0, 0)) Hour)
             [ "15 febbraio al mattino"
             , "mattino di 15 febbraio"
             ]
  , examples (datetime (2013, 2, 12, 20, 0, 0) Hour)
             [ "8 di stasera"
             , "8 della sera"
             ]
  , examples (datetime (2013, 9, 20, 19, 30, 0) Minute)
             [ "venerdÃ¬ 20 settembre alle 7:30 del pomeriggio"
             ]
  , examples (datetime (2013, 2, 16, 9, 0, 0) Hour)
             [ "alle 9 di sabato"
             , "sabato alle 9"
             ]
  , examples (datetimeInterval ((2013, 6, 21, 0, 0, 0), (2013, 9, 24, 0, 0, 0)) Day)
             [ "quest'estate"
             , "questa estate"
             , "in estate"
             ]
  , examples (datetimeInterval ((2012, 12, 21, 0, 0, 0), (2013, 3, 21, 0, 0, 0)) Day)
             [ "quest'inverno"
             , "questo inverno"
             , "in inverno"
             ]
  , examples (datetimeInterval ((2014, 9, 23, 0, 0, 0), (2014, 12, 22, 0, 0, 0)) Day)
             [ "il prossimo autunno"
             ]
  , examples (datetime (2013, 12, 25, 0, 0, 0) Day)
             [ "natale"
             , "il giorno di natale"
             ]
  , examples (datetime (2013, 12, 24, 0, 0, 0) Day)
             [ "vigilia di natale"
             , "alla vigilia"
             , "la vigilia"
             ]
  , examples (datetime (2013, 12, 31, 0, 0, 0) Day)
             [ "vigilia di capodanno"
             , "san silvestro"
             ]
  , examples (datetimeInterval ((2014, 1, 1, 0, 0, 0), (2014, 1, 1, 4, 0, 0)) Hour)
             [ "notte di san silvestro"
             ]
  , examples (datetime (2014, 1, 1, 0, 0, 0) Day)
             [ "capodanno"
             , "primo dell'anno"
             ]
  , examples (datetime (2014, 1, 6, 0, 0, 0) Day)
             [ "epifania"
             , "befana"
             ]
  , examples (datetime (2013, 2, 14, 0, 0, 0) Day)
             [ "san valentino"
             , "festa degli innamorati"
             ]
  , examples (datetime (2013, 3, 19, 0, 0, 0) Day)
             [ "festa del papÃ "
             , "festa del papa"
             , "festa di san giuseppe"
             , "san giuseppe"
             ]
  , examples (datetime (2013, 4, 25, 0, 0, 0) Day)
             [ "anniversario della liberazione"
             , "la liberazione"
             , "alla liberazione"
             ]
  , examples (datetime (2013, 5, 1, 0, 0, 0) Day)
             [ "festa del lavoro"
             , "festa dei lavoratori"
             , "giorno dei lavoratori"
             , "primo maggio"
             ]
  , examples (datetime (2013, 5, 12, 0, 0, 0) Day)
             [ "festa della mamma"
             ]
  , examples (datetime (2013, 6, 2, 0, 0, 0) Day)
             [ "festa della repubblica"
             , "la repubblica"
             , "repubblica"
             ]
  , examples (datetime (2013, 8, 15, 0, 0, 0) Day)
             [ "ferragosto"
             , "assunzione"
             ]
  , examples (datetime (2013, 10, 31, 0, 0, 0) Day)
             [ "halloween"
             ]
  , examples (datetime (2013, 11, 1, 0, 0, 0) Day)
             [ "tutti i santi"
             , "ognissanti"
             , "festa dei santi"
             , "il giorno dei santi"
             ]
  , examples (datetime (2013, 11, 2, 0, 0, 0) Day)
             [ "giorno dei morti"
             , "commemorazione dei defunti"
             ]
  , examples (datetime (2013, 11, 2, 2, 0, 0) Hour)
             [ "ai morti alle 2"
             ]
  , examples (datetime (2013, 12, 8, 0, 0, 0) Day)
             [ "immacolata"
             , "immacolata concezione"
             , "all'immacolata"
             ]
  , examples (datetime (2013, 12, 8, 18, 0, 0) Hour)
             [ "all'immacolata alle 18"
             ]
  , examples (datetime (2013, 12, 26, 0, 0, 0) Day)
             [ "santo stefano"
             ]
  , examples (datetimeInterval ((2013, 2, 12, 18, 0, 0), (2013, 2, 13, 0, 0, 0)) Hour)
             [ "questa sera"
             , "sta sera"
             , "stasera"
             , "in serata"
             , "nella sera"
             , "verso sera"
             , "la sera"
             , "alla sera"
             , "la serata"
             , "nella serata"
             ]
  , examples (datetimeInterval ((2013, 2, 13, 4, 0, 0), (2013, 2, 13, 12, 0, 0)) Hour)
             [ "domani mattina"
             , "domattina"
             ]
  , examples (datetimeInterval ((2013, 2, 12, 4, 30, 0), (2013, 2, 18, 0, 0, 0)) Second)
             [ "in settimana"
             , "per la settimana"
             ]
  , examples (datetimeInterval ((2013, 2, 13, 0, 0, 0), (2013, 2, 13, 4, 0, 0)) Hour)
             [ "stanotte"
             , "nella notte"
             , "in nottata"
             ]
  , examples (datetimeInterval ((2013, 2, 8, 18, 0, 0), (2013, 2, 11, 0, 0, 0)) Hour)
             [ "ultimo weekend"
             ]
  , examples (datetimeInterval ((2013, 2, 13, 18, 0, 0), (2013, 2, 14, 0, 0, 0)) Hour)
             [ "domani in serata"
             , "domani sera"
             , "nella serata di domani"
             ]
  , examples (datetimeInterval ((2013, 2, 14, 0, 0, 0), (2013, 2, 14, 4, 0, 0)) Hour)
             [ "domani notte"
             , "domani in nottata"
             , "nella nottata di domani"
             , "nella notte di domani"
             ]
  , examples (datetimeInterval ((2013, 2, 13, 12, 0, 0), (2013, 2, 13, 14, 0, 0)) Hour)
             [ "domani a pranzo"
             ]
  , examples (datetimeInterval ((2013, 2, 11, 18, 0, 0), (2013, 2, 12, 0, 0, 0)) Hour)
             [ "ieri sera"
             ]
  , examples (datetimeInterval ((2013, 2, 15, 18, 0, 0), (2013, 2, 18, 0, 0, 0)) Hour)
             [ "questo weekend"
             , "questo week-end"
             ]
  , examples (datetimeInterval ((2013, 2, 18, 4, 0, 0), (2013, 2, 18, 12, 0, 0)) Hour)
             [ "lunedÃ¬ mattina"
             , "nella mattinata di lunedÃ¬"
             , "lunedÃ¬ in mattinata"
             , "lunedÃ¬ nella mattina"
             ]
  , examples (datetimeInterval ((2013, 2, 15, 4, 0, 0), (2013, 2, 15, 12, 0, 0)) Hour)
             [ "il 15 febbraio in mattinata"
             , "mattina del 15 febbraio"
             , "15 febbraio mattina"
             ]
  , examples (datetimeInterval ((2013, 2, 12, 4, 29, 58), (2013, 2, 12, 4, 30, 0)) Second)
             [ "gli ultimi 2 secondi"
             , "gli ultimi due secondi"
             , "i 2 secondi passati"
             , "i due secondi passati"
             ]
  , examples (datetimeInterval ((2013, 2, 12, 4, 30, 1), (2013, 2, 12, 4, 30, 4)) Second)
             [ "i prossimi 3 secondi"
             , "i prossimi tre secondi"
             , "nei prossimi tre secondi"
             ]
  , examples (datetimeInterval ((2013, 2, 12, 4, 28, 0), (2013, 2, 12, 4, 30, 0)) Minute)
             [ "gli ultimi 2 minuti"
             , "gli ultimi due minuti"
             , "i 2 minuti passati"
             , "i due minuti passati"
             ]
  , examples (datetimeInterval ((2013, 2, 12, 4, 31, 0), (2013, 2, 12, 4, 34, 0)) Minute)
             [ "i prossimi 3 minuti"
             , "nei prossimi 3 minuti"
             , "i prossimi tre minuti"
             ]
  , examples (datetimeInterval ((2013, 2, 12, 2, 0, 0), (2013, 2, 12, 4, 0, 0)) Hour)
             [ "le ultime 2 ore"
             , "le ultime due ore"
             , "nelle ultime due ore"
             , "le scorse due ore"
             , "le due ore scorse"
             , "le scorse 2 ore"
             , "le 2 ore scorse"
             , "nelle 2 ore scorse"
             ]
  , examples (datetimeInterval ((2013, 2, 11, 4, 0, 0), (2013, 2, 12, 4, 0, 0)) Hour)
             [ "le ultime 24 ore"
             , "le ultime ventiquattro ore"
             , "le 24 ore passate"
             , "nelle 24 ore scorse"
             , "le ventiquattro ore passate"
             ]
  , examples (datetimeInterval ((2013, 2, 12, 5, 0, 0), (2013, 2, 12, 8, 0, 0)) Hour)
             [ "le prossime 3 ore"
             , "prossime tre ore"
             , "nelle prossime 3 ore"
             ]
  , examples (datetimeInterval ((2013, 2, 10, 0, 0, 0), (2013, 2, 12, 0, 0, 0)) Day)
             [ "gli ultimi 2 giorni"
             , "gli ultimi due giorni"
             , "negli ultimi 2 giorni"
             , "i 2 giorni passati"
             , "i due giorni passati"
             , "nei due giorni passati"
             , "gli scorsi due giorni"
             , "i 2 giorni scorsi"
             , "i due giorni scorsi"
             ]
  , examples (datetimeInterval ((2013, 2, 13, 0, 0, 0), (2013, 2, 16, 0, 0, 0)) Day)
             [ "prossimi 3 giorni"
             , "i prossimi tre giorni"
             , "nei prossimi 3 giorni"
             , "prossimi giorni"
             , "nei prossimi giorni"
             ]
  , examples (datetimeInterval ((2013, 1, 28, 0, 0, 0), (2013, 2, 11, 0, 0, 0)) Week)
             [ "le ultime 2 settimane"
             , "le ultime due settimane"
             , "le 2 ultime settimane"
             , "le due ultime settimane"
             , "nelle 2 ultime settimane"
             ]
  , examples (datetimeInterval ((2013, 2, 18, 0, 0, 0), (2013, 3, 11, 0, 0, 0)) Week)
             [ "prossime 3 settimane"
             , "le prossime tre settimane"
             , "le 3 prossime settimane"
             , "nelle prossime 3 settimane"
             , "le tre prossime settimane"
             ]
  , examples (datetimeInterval ((2012, 12, 0, 0, 0, 0), (2013, 2, 0, 0, 0, 0)) Month)
             [ "gli ultimi 2 mesi"
             , "gli ultimi due mesi"
             , "i 2 mesi passati"
             , "nei 2 mesi passati"
             , "i due mesi passati"
             , "i due mesi scorsi"
             , "i 2 mesi scorsi"
             , "negli scorsi due mesi"
             , "gli scorsi due mesi"
             , "gli scorsi 2 mesi"
             ]
  , examples (datetimeInterval ((2013, 3, 0, 0, 0, 0), (2013, 6, 0, 0, 0, 0)) Month)
             [ "i prossimi 3 mesi"
             , "i prossimi tre mesi"
             , "prossimi 3 mesi"
             , "i 3 prossimi mesi"
             , "i tre prossimi mesi"
             , "nei prossimi tre mesi"
             ]
  , examples (datetimeInterval ((2011, 0, 0, 0, 0, 0), (2013, 0, 0, 0, 0, 0)) Year)
             [ "gli ultimi 2 anni"
             , "gli ultimi due anni"
             , "negli ultimi 2 anni"
             , "i 2 anni passati"
             , "i due anni passati"
             , "i 2 anni scorsi"
             , "i due anni scorsi"
             , "gli scorsi due anni"
             , "gli scorsi 2 anni"
             ]
  , examples (datetimeInterval ((2014, 0, 0, 0, 0, 0), (2017, 0, 0, 0, 0, 0)) Year)
             [ "i prossimi 3 anni"
             , "i prossimi tre anni"
             , "nei tre prossimi anni"
             ]
  , examples (datetimeInterval ((2013, 7, 13, 0, 0, 0), (2013, 7, 16, 0, 0, 0)) Day)
             [ "13-15 luglio"
             , "dal 13 al 15 luglio"
             , "tra il 13 e il 15 luglio"
             , "tra 13 e 15 luglio"
             , "dal tredici al quindici luglio"
             , "13 luglio - 15 luglio"
             ]
  , examples (datetimeInterval ((2013, 3, 3, 0, 0, 0), (2013, 3, 6, 0, 0, 0)) Day)
             [ "dal 3 al 5"
             , "tra il 3 e il 5"
             , "dal tre al cinque"
             ]
  , examples (datetimeInterval ((2013, 8, 8, 0, 0, 0), (2013, 8, 13, 0, 0, 0)) Day)
             [ "8 ago - 12 ago"
             ]
  , examples (datetimeInterval ((2013, 2, 13, 0, 0, 0), (2013, 2, 15, 0, 0, 0)) Day)
             [ "da domani a giovedÃ¬"
             ]
  , examples (datetimeInterval ((2013, 2, 12, 9, 30, 0), (2013, 2, 12, 11, 1, 0)) Minute)
             [ "9:30 - 11:00"
             ]
  , examples (datetimeInterval ((2013, 2, 14, 9, 30, 0), (2013, 2, 14, 11, 1, 0)) Minute)
             [ "dalle 9:30 alle 11:00 di giovedÃ¬"
             , "tra le 9:30 e le 11:00 di giovedÃ¬"
             , "9:30 - 11:00 giovedÃ¬"
             , "giovedÃ¬ dalle 9:30 alle 11:00"
             , "giovedÃ¬ tra le 9:30 e le 11:00"
             ]
  , examples (datetimeInterval ((2013, 2, 14, 9, 0, 0), (2013, 2, 14, 12, 0, 0)) Hour)
             [ "dalle 9 alle 11 di giovedÃ¬"
             , "tra le 9 e le 11 di giovedÃ¬"
             , "9 - 11 giovedÃ¬"
             , "giovedÃ¬ dalle nove alle undici"
             , "giovedÃ¬ tra le nove e le undici"
             ]
  , examples (datetimeInterval ((2013, 2, 14, 3, 0, 0), (2013, 2, 14, 14, 0, 0)) Hour)
             [ "dalle tre all'una di giovedÃ¬"
             ]
  , examples (datetimeInterval ((2013, 2, 13, 0, 0, 0), (2013, 2, 13, 3, 0, 0)) Hour)
             [ "dalla mezzanotte alle 2"
             ]
  , examples (datetimeInterval ((2013, 2, 13, 15, 0, 0), (2013, 2, 13, 17, 1, 0)) Minute)
             [ "domani dalle 15:00 alle 17:00"
             ]
  , examples (datetimeInterval ((2013, 2, 12, 11, 30, 0), (2013, 2, 12, 13, 31, 0)) Minute)
             [ "11:30-13:30"
             ]
  , examples (datetime (2013, 9, 21, 13, 30, 0) Minute)
             [ "13:30 di sabato 21 settembre"
             , "13:30 del 21 settembre"
             ]
  , examples (datetime (2013, 2, 26, 0, 0, 0) Day)
             [ "in due settimane"
             ]
  , examples (datetimeInterval ((2013, 2, 12, 4, 30, 0), (2013, 2, 12, 14, 0, 0)) Second)
             [ "fino alle 14:00"
             ]
  , examples (datetimeOpenInterval Before (2013, 2, 12, 14, 0, 0) Minute)
             [ "entro le 14:00"
             ]
  , examples (datetimeOpenInterval Before (2013, 3, 1, 0, 0, 0) Month)
             [ "entro la fine del mese"
             ]
  , examples (datetimeOpenInterval Before (2014, 1, 1, 0, 0, 0) Year)
             [ "entro la fine dell'anno"
             ]
  , examples (datetimeInterval ((2013, 2, 12, 4, 30, 0), (2013, 3, 1, 0, 0, 0)) Second)
             [ "fino alla fine del mese"
             ]
  , examples (datetimeInterval ((2013, 2, 12, 4, 30, 0), (2014, 1, 1, 0, 0, 0)) Second)
             [ "fino alla fine dell'anno"
             ]
  , examples (datetime (2013, 2, 13, 1, 0, 0) Minute)
             [ "alle 4 CET"
             ]
  , examples (datetime (2013, 2, 12, 13, 0, 0) Minute)
             [ "alle 16 CET"
             ]
  , examples (datetime (2013, 2, 14, 6, 0, 0) Minute)
             [ "giovedÃ¬ alle 8:00 GMT"
             , "giovedÃ¬ alle 8:00 gmt"
             ]
  , examples (datetime (2013, 2, 13, 14, 0, 0) Hour)
             [ "domani alle 14"
             ]
  , examples (datetime (2013, 2, 12, 14, 0, 0) Hour)
             [ "alle 14"
             , "alle 2 del pomeriggio"
             ]
  , examples (datetime (2013, 4, 25, 16, 0, 0) Minute)
             [ "25/4 alle 16:00"
             ]
  , examples (datetime (2013, 2, 13, 15, 0, 0) Hour)
             [ "3 del pomeriggio di domani"
             , "15 del pomeriggio di domani"
             ]
  , examples (datetimeOpenInterval After (2013, 2, 12, 14, 0, 0) Hour)
             [ "dopo le 14"
             , "dalle 14"
             ]
  , examples (datetimeOpenInterval After (2013, 2, 13, 0, 0, 0) Hour)
             [ "dalla mezzanotte"
             ]
  , examples (datetimeOpenInterval After (2013, 2, 13, 14, 0, 0) Hour)
             [ "domani dopo le 14"
             , "domani dalle 14"
             ]
  , examples (datetimeOpenInterval Before (2013, 2, 12, 11, 0, 0) Hour)
             [ "prima delle 11"
             ]
  , examples (datetimeOpenInterval Before (2013, 2, 14, 11, 0, 0) Hour)
             [ "dopodomani prima delle 11"
             ]
  , examples (datetimeOpenInterval Before (2013, 2, 14, 12, 0, 0) Hour)
             [ "giovedÃ¬ entro mezzogiorno"
             ]
  , examples (datetimeOpenInterval After (2013, 2, 14, 0, 0, 0) Day)
             [ "da dopodomani"
             , "da giovedÃ¬"
             ]
  , examples (datetimeOpenInterval After (2013, 3, 1, 0, 0, 0) Day)
             [ "dal primo"
             ]
  , examples (datetimeOpenInterval After (2013, 2, 20, 0, 0, 0) Day)
             [ "dal 20"
             ]
  , examples (datetimeOpenInterval Before (2013, 2, 15, 0, 0, 0) Day)
             [ "entro il 15"
             ]
  , examples (datetimeOpenInterval Before (2013, 4, 20, 0, 0, 0) Day)
             [ "prima del 20 aprile"
             ]
  , examples (datetimeInterval ((2013, 2, 12, 12, 0, 0), (2013, 2, 12, 19, 0, 0)) Hour)
             [ "nel pomeriggio"
             ]
  , examples (datetime (2013, 2, 12, 13, 30, 0) Minute)
             [ "alle 13:30"
             , "13:30"
             , "1:30 del pomeriggio"
             ]
  , examples (datetime (2013, 2, 12, 4, 45, 0) Second)
             [ "in 15 minuti"
             , "tra 15 minuti"
             ]
  , examples (datetime (2013, 2, 12, 10, 30, 0) Minute)
             [ "10:30"
             ]
  , examples (datetimeInterval ((2013, 2, 12, 4, 0, 0), (2013, 2, 12, 12, 0, 0)) Hour)
             [ "questa mattina"
             , "questa mattinata"
             , "questo mattino"
             ]
  , examples (datetime (2013, 2, 25, 0, 0, 0) Day)
             [ "prossimo lunedÃ¬"
             ]
  , examples (datetime (2013, 2, 12, 12, 0, 0) Hour)
             [ "alle 12"
             , "a mezzogiorno"
             ]
  , examples (datetime (2013, 2, 13, 0, 0, 0) Hour)
             [ "alle 24"
             , "a mezzanotte"
             ]
  , examples (datetime (2013, 3, 1, 0, 0, 0) Month)
             [ "marzo"
             , "in marzo"
             ]
  , examples (datetime (2013, 8, 15, 0, 0, 0) Day)
             [ "gio 15"
             ]
  , examples (datetime (2013, 2, 5, 4, 0, 0) Hour)
             [ "7 giorni fa"
             ]
  , examples (datetime (2013, 2, 5, 0, 0, 0) Day)
             [ "una settimana fa"
             , "1 settimana fa"
             ]
  , examples (datetime (2013, 1, 22, 0, 0, 0) Day)
             [ "tre settimane fa"
             , "3 settimane fa"
             ]
  , examples (datetime (2012, 11, 12, 0, 0, 0) Day)
             [ "tre mesi fa"
             , "3 mesi fa"
             ]
  , examples (datetime (2011, 2, 1, 0, 0, 0) Month)
             [ "due anni fa"
             , "2 anni fa"
             ]
   , examples (datetimeHoliday (2013, 12, 18, 0, 0, 0) Day "Giornata della lingua araba")
             [ "giornata della lingua araba"
             ]
   , examples (datetimeHoliday (2013, 3, 1, 0, 0, 0) Day "Giornata Mondiale contro la discriminazione")
             [ "giornata mondiale contro la discriminazione"
             ]
   , examples (datetimeHoliday (2019, 7, 6, 0, 0, 0) Day "Giornata Internazionale delle cooperative")
             [ "giornata internazionale delle cooperative del 2019"
             ]
   , examples (datetimeHoliday (2013, 11, 17, 0, 0, 0) Day "Giornata Mondiale della PrematuritÃ ")
             [ "giornata mondiale dei prematuri"
             , "giornata mondiale della prematurita"
             , "giornata mondiale della prematuritÃ "
             ]
   , examples (datetimeHoliday (2013, 5, 25, 0, 0, 0) Day "Giornata dell'Africa")
             [ "giornata della liberazione africana"
             , "giornata dell'unitÃ  africana"
             , "giornata dell'africa"
             ]
  ]