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

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

import Data.Semigroup ((<>))
import Data.String
import Prelude
import qualified Data.Text as Text

import Duckling.Dimensions.Types
import Duckling.Duration.Helpers
import Duckling.Duration.Types (DurationData(..))
import Duckling.Numeral.Helpers (parseInt, parseInteger)
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

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
    , 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)
-> (DurationData -> Token) -> DurationData -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 -> Maybe Token) -> DurationData -> Maybe 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
  }

ruleCompositeDuration1 :: Rule
ruleCompositeDuration1 :: Rule
ruleCompositeDuration1 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"composite <duration>"
  , pattern :: Pattern
pattern =
    [ 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
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)
-> (DurationData -> Token) -> DurationData -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 -> Maybe Token) -> DurationData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> DurationData
duration a
Grain
g Int
1 DurationData -> DurationData -> DurationData
forall a. Semigroup a => a -> a -> a
<> a
DurationData
dd
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDurationYear :: Rule
ruleDurationYear :: Rule
ruleDurationYear = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<integer> year"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isNatural
    , String -> PatternItem
regex String
"წელიწად(ის)?(ი)?(ში)?|წლი(ის)?(ში)?|წელშ?ი"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Numeral NumeralData{TNumeral.value = v}:[Token]
_) ->
        Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> (Int -> Token) -> Int -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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) -> (Int -> DurationData) -> Int -> Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Grain -> Int -> DurationData
duration Grain
TG.Month (Int -> Maybe Token) -> Int -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int
12 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor Double
v
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDurationAndHalfYear :: Rule
ruleDurationAndHalfYear :: Rule
ruleDurationAndHalfYear = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<integer> and an half year"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isNatural
    , String -> PatternItem
regex String
"წელიწადნახევა?(რის)?(რი)?(რში)?|წლინახევრ(ის)?(არში)?"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Numeral NumeralData{TNumeral.value = v}:[Token]
_) ->
        Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> (Int -> Token) -> Int -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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) -> (Int -> DurationData) -> Int -> Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Grain -> Int -> DurationData
duration Grain
TG.Month (Int -> Maybe Token) -> Int -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int
6 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
12 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor Double
v
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDurationAndHalfYear1 :: Rule
ruleDurationAndHalfYear1 :: Rule
ruleDurationAndHalfYear1 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<integer> and an half year"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"წელიწადნახევა?(რის)?(რი)?(რში)?|წლინახევრ(ის)?(არში)?"
    ]
  , prod :: Production
prod = Maybe Token -> Production
forall a b. a -> b -> a
const (Maybe Token -> Production) -> Maybe Token -> Production
forall a b. (a -> b) -> a -> b
$ Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> (Int -> Token) -> Int -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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) -> (Int -> DurationData) -> Int -> Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Grain -> Int -> DurationData
duration Grain
TG.Month (Int -> Maybe Token) -> Int -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int
18
  }

ruleDurationAndHalfMonth :: Rule
ruleDurationAndHalfMonth :: Rule
ruleDurationAndHalfMonth = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<integer> and an half month"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isNatural
    , String -> PatternItem
regex String
"თვენახევა?(რის)?(რი)?(რში)?"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Numeral NumeralData{TNumeral.value = v}:[Token]
_) ->
        Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> (Int -> Token) -> Int -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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) -> (Int -> DurationData) -> Int -> Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Grain -> Int -> DurationData
duration Grain
TG.Day (Int -> Maybe Token) -> Int -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int
15 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
30 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor Double
v
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDurationAndHalfMonth1 :: Rule
ruleDurationAndHalfMonth1 :: Rule
ruleDurationAndHalfMonth1 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"month and an half month"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"თვენახევა?(რის)?(რი)?(რში)?"
    ]
  , prod :: Production
prod = Maybe Token -> Production
forall a b. a -> b -> a
const (Maybe Token -> Production) -> Maybe Token -> Production
forall a b. (a -> b) -> a -> b
$ Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> (Int -> Token) -> Int -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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) -> (Int -> DurationData) -> Int -> Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Grain -> Int -> DurationData
duration Grain
TG.Day (Int -> Maybe Token) -> Int -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int
45
  }

ruleDurationAndHalfWeek :: Rule
ruleDurationAndHalfWeek :: Rule
ruleDurationAndHalfWeek = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<integer> and an half week"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isNatural
    , String -> PatternItem
regex String
"თვენახევა?(რის)?(რი)?(რში)?"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Numeral NumeralData{TNumeral.value = v}:[Token]
_) ->
        Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> (Int -> Token) -> Int -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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) -> (Int -> DurationData) -> Int -> Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Grain -> Int -> DurationData
duration Grain
TG.Day (Int -> Maybe Token) -> Int -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int
3 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
7 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor Double
v
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDurationAndHalfWeek1 :: Rule
ruleDurationAndHalfWeek1 :: Rule
ruleDurationAndHalfWeek1 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"week and an half week"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"კვირანახევა?(რის)?(რი)?(რში)?"
    ]
  , prod :: Production
prod = Maybe Token -> Production
forall a b. a -> b -> a
const (Maybe Token -> Production) -> Maybe Token -> Production
forall a b. (a -> b) -> a -> b
$ Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> (Int -> Token) -> Int -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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) -> (Int -> DurationData) -> Int -> Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Grain -> Int -> DurationData
duration Grain
TG.Day (Int -> Maybe Token) -> Int -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int
10
  }

rules :: [Rule]
rules :: [Rule]
rules =
  [ Rule
ruleCompositeDuration
  , Rule
ruleCompositeDuration1
  , Rule
ruleDurationAndHalfYear
  , Rule
ruleDurationAndHalfYear1
  , Rule
ruleDurationAndHalfMonth
  , Rule
ruleDurationAndHalfMonth1
  , Rule
ruleDurationAndHalfWeek
  , Rule
ruleDurationAndHalfWeek1
  , Rule
ruleDurationYear
  ]