-- 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 LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}

module Duckling.Duration.HI.Rules
  ( rules
  ) where

import Data.String
import Data.HashMap.Strict (HashMap)
import Data.Text (Text)
import Prelude
import qualified Data.HashMap.Strict as HashMap
import qualified Data.Text as Text

import Duckling.Dimensions.Types
import Duckling.Duration.Helpers
import Duckling.Duration.Types (DurationData(..))
import Duckling.Numeral.Types (NumeralData (..))
import Duckling.Regex.Types
import Duckling.Types
import qualified Duckling.Duration.Types as TDuration
import qualified Duckling.Numeral.Types as TNumeral
import qualified Duckling.TimeGrain.Types as TG

avadhiMap :: HashMap Text TG.Grain
avadhiMap :: HashMap Text Grain
avadhiMap = [(Text, Grain)] -> HashMap Text Grain
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HashMap.fromList
  [ (Text
"मिनट" , Grain
TG.Minute)
  , (Text
"क्षण", Grain
TG.Minute)
  , (Text
"घंटा" , Grain
TG.Hour)
  , (Text
"दिवस" , Grain
TG.Day)
  , (Text
"दिन"  , Grain
TG.Day)
  , (Text
"महीना", Grain
TG.Month)
  , (Text
"माह", Grain
TG.Month)
  , (Text
"मास", Grain
TG.Month)
  , (Text
"वर्ष" , Grain
TG.Year)
  , (Text
"साल"  , Grain
TG.Year)
  , (Text
"बरस", Grain
TG.Year)
  ]

ruleAadha :: Rule
ruleAadha :: Rule
ruleAadha = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"half of a duration"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"आधा ((साल|वर्ष|बरस)|(महीना|मास|माह)|(दिन|दिवस)|(घंटा)|(मिनट|क्षण))"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (x:_)):[Token]
_) -> do
        Grain
grain <- Text -> HashMap Text Grain -> Maybe Grain
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup (Text -> Text
Text.toLower Text
x) HashMap Text Grain
avadhiMap
        Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration (DurationData -> Token) -> Maybe DurationData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Grain -> Int -> Maybe DurationData
nPlusOneHalf Grain
grain Int
0
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDurationPandrahMinat :: Rule
ruleDurationPandrahMinat :: Rule
ruleDurationPandrahMinat = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"quarter of an hour"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"पंद्रह मिनट"
    ]
  , prod :: Production
prod = \[Token]
_ -> Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration (DurationData -> Token) -> DurationData -> Token
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> DurationData
duration Grain
TG.Minute Int
15
  }

ruleDurationPakhwaada :: Rule
ruleDurationPakhwaada :: Rule
ruleDurationPakhwaada = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"fortnight"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"((एक पखवाड़ा)|(पखवाड़ा))"
    ]
  , prod :: Production
prod = \[Token]
_ -> Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration (DurationData -> Token) -> DurationData -> Token
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> DurationData
duration Grain
TG.Day Int
14
  }

ruleDurationDin :: Rule
ruleDurationDin :: Rule
ruleDurationDin = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"a day"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"((एक दिन)|(एक दिवस)|(दिन|दिवस))"
    ]
  , prod :: Production
prod = \[Token]
_ -> Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration (DurationData -> Token) -> DurationData -> Token
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> DurationData
duration Grain
TG.Day Int
1
  }

ruleDurationEkSaal :: Rule
ruleDurationEkSaal :: Rule
ruleDurationEkSaal = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"one year"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"एक (साल|वर्ष|बरस)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration (DurationData -> Token) -> DurationData -> Token
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> DurationData
duration Grain
TG.Year Int
1
  }

ruleDurationPreciseImprecise :: Rule
ruleDurationPreciseImprecise :: Rule
ruleDurationPreciseImprecise = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"about|exactly <duration>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(लगभग|बिल्कुल|केवल)"
    , Dimension DurationData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension DurationData
Duration
    ]
    , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
        (Token
_:Token
token:[Token]
_) -> Token -> Maybe Token
forall a. a -> Maybe a
Just Token
token
        [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

rulePauneDuration :: Rule
rulePauneDuration :: Rule
rulePauneDuration = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"Paune duration"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"पौने"
    , Predicate -> PatternItem
Predicate Predicate
isNatural
    , Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    ]
  , prod :: Production
prod = \case
      (Token
_:
       Token Dimension a
Numeral NumeralData{TNumeral.value = v}:
       Token Dimension a
TimeGrain a
grain:
       [Token]
_) -> Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration (DurationData -> Token) -> Maybe DurationData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Grain -> Int -> Maybe DurationData
timesThreeQuarter a
Grain
grain (Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor (Double
v Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
1))
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleSavaDuration :: Rule
ruleSavaDuration :: Rule
ruleSavaDuration = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"Sava duration"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"सवा"
    , Predicate -> PatternItem
Predicate Predicate
isNatural
    , Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    ]
  , prod :: Production
prod = \case
      (Token
_:
       Token Dimension a
Numeral NumeralData{TNumeral.value = v}:
       Token Dimension a
TimeGrain a
grain:
       [Token]
_) -> Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration (DurationData -> Token) -> Maybe DurationData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Grain -> Int -> Maybe DurationData
timesOneQuarter a
Grain
grain (Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor Double
v)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleSaadeDuration :: Rule
ruleSaadeDuration :: Rule
ruleSaadeDuration = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"Saade duration"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"साढ़े|साड़े"
    , Predicate -> PatternItem
Predicate Predicate
isNatural
    , Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    ]
  , prod :: Production
prod = \case
      (Token
_:
        Token Dimension a
Numeral NumeralData{TNumeral.value = v}:
        Token Dimension a
TimeGrain a
grain:
        [Token]
_) -> Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration (DurationData -> Token) -> Maybe DurationData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Grain -> Int -> Maybe DurationData
nPlusOneHalf a
Grain
grain (Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor Double
v)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleCompositeDuration :: Rule
ruleCompositeDuration :: Rule
ruleCompositeDuration = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"composite <duration>"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isNatural
    , Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    , Dimension DurationData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension DurationData
Duration
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Numeral NumeralData{TNumeral.value = v}:
       Token Dimension a
TimeGrain a
g:
       Token Dimension a
Duration dd :: a
dd@DurationData{TDuration.grain = dg}:
       [Token]
_) | a
g a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
Grain
dg -> Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration (DurationData -> Token) -> DurationData -> Token
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> DurationData
duration a
Grain
g (Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor Double
v) DurationData -> DurationData -> DurationData
forall a. Semigroup a => a -> a -> a
<> a
DurationData
dd
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleCompositeDurationCommasAnd :: Rule
ruleCompositeDurationCommasAnd :: Rule
ruleCompositeDurationCommasAnd = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"composite <duration> (with ,/और)"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isNatural
    , Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    , String -> PatternItem
regex String
",|और"
    , Dimension DurationData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension DurationData
Duration
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Numeral NumeralData{TNumeral.value = v}:
        Token Dimension a
TimeGrain a
g:
        Token
_:
        Token Dimension a
Duration dd :: a
dd@DurationData{TDuration.grain = dg}:
        [Token]
_) | a
g a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
Grain
dg -> Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration (DurationData -> Token) -> DurationData -> Token
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> DurationData
duration a
Grain
g (Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor Double
v) DurationData -> DurationData -> DurationData
forall a. Semigroup a => a -> a -> a
<> a
DurationData
dd
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleNAndHalfDuration :: Rule
ruleNAndHalfDuration :: Rule
ruleNAndHalfDuration = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"डेढ़|ढाई <duration>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(डेढ़|ढाई)"
    , Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):
       Token Dimension a
TimeGrain a
grain:
       [Token]
_) -> do
        Int
h <- case Text -> Text
Text.toLower Text
match of
          Text
"डेढ़" -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1
          Text
"ढाई" -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
2
          Text
_ -> Maybe Int
forall a. Maybe a
Nothing
        Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration (DurationData -> Token) -> Maybe DurationData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Grain -> Int -> Maybe DurationData
nPlusOneHalf a
Grain
grain Int
h
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

rules :: [Rule]
rules :: [Rule]
rules =
  [  Rule
ruleDurationPandrahMinat
  ,  Rule
ruleDurationPakhwaada
  ,  Rule
ruleDurationDin
  ,  Rule
ruleAadha
  ,  Rule
ruleDurationEkSaal
  ,  Rule
ruleDurationPreciseImprecise
  ,  Rule
rulePauneDuration
  ,  Rule
ruleSavaDuration
  ,  Rule
ruleSaadeDuration
  ,  Rule
ruleCompositeDuration
  ,  Rule
ruleCompositeDurationCommasAnd
  ,  Rule
ruleNAndHalfDuration
  ]