-- 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.PhoneNumber.AR.Rules (rules) where

import Duckling.Dimensions.Types
import Duckling.Numeral.AR.Helpers
  ( parseArabicIntAsText
  , parseArabicIntegerFromText
  )
import Duckling.PhoneNumber.Types (PhoneNumberData(..))
import Duckling.Regex.Types
import Duckling.Types
import Prelude

import qualified Data.Text as Text
import qualified Duckling.PhoneNumber.Types as TPhoneNumber

rulePhoneNumber :: Rule
rulePhoneNumber :: Rule
rulePhoneNumber = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"phone number"
  , pattern :: Pattern
pattern =
    -- Arabic is a right to left langauge except for numbers, which are read
    -- left to right. This regex uses the unicode range for Arabic numbers
    -- [\1632-\1641] to make the code easier to read and maintain. The unicode
    -- sequence \1601\1585\1593\1610, corresponding to فرعي, is a popular
    -- Arabic equivalent for "extension" and is used in this regex.
    [ String -> PatternItem
regex (String -> PatternItem) -> String -> PatternItem
forall a b. (a -> b) -> a -> b
$
        String
"(?:\\(?\\+([\1632-\1641]{1,2})\\)?[\\s-\\.]*)?" String -> String -> String
forall a. [a] -> [a] -> [a]
++ -- area code
        String
"((?=[-\1632-\1641()\\s\\.]{6,16}(?:\\s*(?:e?xt?|\1601\1585\1593\1610)?\\.?\\s*(?:[\1632-\1641]{1,20}))?(?:[^\1632-\1641]+|$))(?:[\1632-\1641(]{1,20}(?:[-)\\s\\.]*[\1632-\1641]{1,20}){0,20}){1,20})" String -> String -> String
forall a. [a] -> [a] -> [a]
++ -- nums
        String
"(?:\\s*(?:e?xt?|\1601\1585\1593\1610)\\.?\\s*([\1632-\1641]{1,20}))?" -- extension
    ]
  , prod :: Production
prod = \[Token]
xs -> case [Token]
xs of
      (Token Dimension a
RegexMatch (GroupMatch (code:nums:ext:_)):[Token]
_) ->
        let
            mnums :: Text
mnums = Text -> Text
parseArabicIntAsText (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Text -> Text
cleanup Text
nums
            cleanup :: Text -> Text
cleanup = (Char -> Bool) -> Text -> Text
Text.filter (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isWhitespace)
            isWhitespace :: Char -> Bool
isWhitespace Char
x = Char -> String -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
elem Char
x [Char
'.', Char
' ', Char
'-', Char
'\t', Char
'(', Char
')']
        in Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Dimension PhoneNumberData -> PhoneNumberData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension PhoneNumberData
PhoneNumber (PhoneNumberData -> Token) -> PhoneNumberData -> Token
forall a b. (a -> b) -> a -> b
$ PhoneNumberData :: Maybe Integer -> Text -> Maybe Integer -> PhoneNumberData
PhoneNumberData
          { prefix :: Maybe Integer
TPhoneNumber.prefix = Text -> Maybe Integer
parseArabicIntegerFromText Text
code
          , number :: Text
TPhoneNumber.number = Text
mnums
          , extension :: Maybe Integer
TPhoneNumber.extension = Text -> Maybe Integer
parseArabicIntegerFromText Text
ext
          }
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

rules :: [Rule]
rules :: [Rule]
rules = [Rule
rulePhoneNumber]