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

module Duckling.Ordinal.AR.Rules
  ( rules
  ) where

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

import Duckling.Dimensions.Types
import Duckling.Numeral.Helpers (parseInt)
import Duckling.Ordinal.Helpers
import Duckling.Regex.Types
import Duckling.Types

ordinalsMap :: HashMap Text Int
ordinalsMap :: HashMap Text Int
ordinalsMap = [(Text, Int)] -> HashMap Text Int
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HashMap.fromList
  [ ( Text
"اول", Int
1 )
  , ( Text
"أول", Int
1 )
  , ( Text
"حاد", Int
1 )
  , ( Text
"حادي", Int
1 )
  , ( Text
"واحد", Int
1 )
  , ( Text
"ثان", Int
2 )
  , ( Text
"ثاني", Int
2 )
  , ( Text
"ثالث", Int
3 )
  , ( Text
"رابع", Int
4 )
  , ( Text
"خامس", Int
5 )
  , ( Text
"سادس", Int
6 )
  , ( Text
"سابع", Int
7 )
  , ( Text
"ثامن", Int
8 )
  , ( Text
"تاسع", Int
9 )
  , ( Text
"عاشر", Int
10 )
  ]

-- حذفنا ون،ين للتوحيد بين المذكر والمؤنث
cardinalsMap :: HashMap Text Int
cardinalsMap :: HashMap Text Int
cardinalsMap = [(Text, Int)] -> HashMap Text Int
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HashMap.fromList
  [ ( Text
"عشر", Int
20 )
  , ( Text
"ثلاث", Int
30 )
  , ( Text
"اربع", Int
40 )
  , ( Text
"خمس", Int
50 )
  , ( Text
"ست", Int
60 )
  , ( Text
"سبع", Int
70 )
  , ( Text
"ثمان", Int
80 )
  , ( Text
"تسع", Int
90 )
  ]

ruleCompositeOrdinals :: Rule
ruleCompositeOrdinals :: Rule
ruleCompositeOrdinals = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"ordinals (composite, e.g., eighty-seven)"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"ال(واحد|حادي?|ثاني?|ثالث|رابع|خامس|سادس|سابع|ثامن|تاسع|عاشر) و ?ال(عشر|ثلاث|اربع|خمس|ست|سبع|ثمان|تسع)(ون|ين)"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (tens:units:_)):[Token]
_) -> do
        Int
tt <- Text -> HashMap Text Int -> Maybe Int
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup (Text -> Text
Text.toLower Text
tens) HashMap Text Int
ordinalsMap
        Int
uu <- Text -> HashMap Text Int -> Maybe Int
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup (Text -> Text
Text.toLower Text
units) HashMap Text Int
cardinalsMap
        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
. Int -> Token
ordinal (Int -> Maybe Token) -> Int -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int
tt Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
uu
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleOrdinals1To10 :: Rule
ruleOrdinals1To10 :: Rule
ruleOrdinals1To10 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"ordinals (first..tenth)"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(?:ال)?([أا]ول|ثاني?|ثالث|رابع|خامس|سادس|سابع|ثامن|تاسع|عاشر)[ةهى]?"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) ->
        Int -> Token
ordinal (Int -> Token) -> Maybe Int -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> HashMap Text Int -> Maybe Int
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup (Text -> Text
Text.toLower Text
match) HashMap Text Int
ordinalsMap
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleOrdinals11 :: Rule
ruleOrdinals11 :: Rule
ruleOrdinals11 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"ordinals (eleventh)"
  , 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
$ Int -> Token
ordinal Int
11
  }

ruleOrdinals12 :: Rule
ruleOrdinals12 :: Rule
ruleOrdinals12 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"ordinals (twelveth)"
  , 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
$ Int -> Token
ordinal Int
12
  }

ruleOrdinals13To19 :: Rule
ruleOrdinals13To19 :: Rule
ruleOrdinals13To19 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"ordinals (thirtieth..nineteenth)"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"ال(ثالث|رابع|خامس|سادس|سابع|ثامن|تاسع)[ةه]? ?عشرة?"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) -> do
        Int
uu <- Text -> HashMap Text Int -> Maybe Int
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup (Text -> Text
Text.toLower Text
match) HashMap Text Int
ordinalsMap
        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
. Int -> Token
ordinal (Int -> Maybe Token) -> Int -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int
10 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
uu
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleOrdinals3 :: Rule
ruleOrdinals3 :: Rule
ruleOrdinals3 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"ordinals (twenty, thirty..ninety)"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"ال(عشر|ثلاث|اربع|خمس|ست|سبع|ثمان|تسع)(ون|ين)"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) ->
        Int -> Token
ordinal (Int -> Token) -> Maybe Int -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> HashMap Text Int -> Maybe Int
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup (Text -> Text
Text.toLower Text
match) HashMap Text Int
cardinalsMap
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

rules :: [Rule]
rules :: [Rule]
rules =
  [ Rule
ruleCompositeOrdinals
  , Rule
ruleOrdinals1To10
  , Rule
ruleOrdinals11
  , Rule
ruleOrdinals12
  , Rule
ruleOrdinals13To19
  , Rule
ruleOrdinals3
  ]