-- 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 DeriveAnyClass #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE NoRebindableSyntax #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeFamilies #-}

module Duckling.CreditCardNumber.Types where

import Control.DeepSeq
import Data.Aeson
import Data.Hashable
import Data.Text (Text)
import qualified Data.Text as Text
import GHC.Generics

import Prelude

import Duckling.Resolve (Resolve(..))

data Issuer
  = Visa
  | Amex
  | Discover
  | Mastercard
  | DinerClub
  | Other
  deriving (Issuer -> Issuer -> Bool
(Issuer -> Issuer -> Bool)
-> (Issuer -> Issuer -> Bool) -> Eq Issuer
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Issuer -> Issuer -> Bool
$c/= :: Issuer -> Issuer -> Bool
== :: Issuer -> Issuer -> Bool
$c== :: Issuer -> Issuer -> Bool
Eq, (forall x. Issuer -> Rep Issuer x)
-> (forall x. Rep Issuer x -> Issuer) -> Generic Issuer
forall x. Rep Issuer x -> Issuer
forall x. Issuer -> Rep Issuer x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Issuer x -> Issuer
$cfrom :: forall x. Issuer -> Rep Issuer x
Generic, Int -> Issuer -> Int
Issuer -> Int
(Int -> Issuer -> Int) -> (Issuer -> Int) -> Hashable Issuer
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: Issuer -> Int
$chash :: Issuer -> Int
hashWithSalt :: Int -> Issuer -> Int
$chashWithSalt :: Int -> Issuer -> Int
Hashable, Eq Issuer
Eq Issuer
-> (Issuer -> Issuer -> Ordering)
-> (Issuer -> Issuer -> Bool)
-> (Issuer -> Issuer -> Bool)
-> (Issuer -> Issuer -> Bool)
-> (Issuer -> Issuer -> Bool)
-> (Issuer -> Issuer -> Issuer)
-> (Issuer -> Issuer -> Issuer)
-> Ord Issuer
Issuer -> Issuer -> Bool
Issuer -> Issuer -> Ordering
Issuer -> Issuer -> Issuer
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Issuer -> Issuer -> Issuer
$cmin :: Issuer -> Issuer -> Issuer
max :: Issuer -> Issuer -> Issuer
$cmax :: Issuer -> Issuer -> Issuer
>= :: Issuer -> Issuer -> Bool
$c>= :: Issuer -> Issuer -> Bool
> :: Issuer -> Issuer -> Bool
$c> :: Issuer -> Issuer -> Bool
<= :: Issuer -> Issuer -> Bool
$c<= :: Issuer -> Issuer -> Bool
< :: Issuer -> Issuer -> Bool
$c< :: Issuer -> Issuer -> Bool
compare :: Issuer -> Issuer -> Ordering
$ccompare :: Issuer -> Issuer -> Ordering
$cp1Ord :: Eq Issuer
Ord, Int -> Issuer -> ShowS
[Issuer] -> ShowS
Issuer -> String
(Int -> Issuer -> ShowS)
-> (Issuer -> String) -> ([Issuer] -> ShowS) -> Show Issuer
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Issuer] -> ShowS
$cshowList :: [Issuer] -> ShowS
show :: Issuer -> String
$cshow :: Issuer -> String
showsPrec :: Int -> Issuer -> ShowS
$cshowsPrec :: Int -> Issuer -> ShowS
Show, Issuer -> ()
(Issuer -> ()) -> NFData Issuer
forall a. (a -> ()) -> NFData a
rnf :: Issuer -> ()
$crnf :: Issuer -> ()
NFData)

instance ToJSON Issuer where
  toJSON :: Issuer -> Value
toJSON = Text -> Value
String (Text -> Value) -> (Issuer -> Text) -> Issuer -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
Text.toLower (Text -> Text) -> (Issuer -> Text) -> Issuer -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
Text.pack (String -> Text) -> (Issuer -> String) -> Issuer -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Issuer -> String
forall a. Show a => a -> String
show

data CreditCardNumberData = CreditCardNumberData
  { CreditCardNumberData -> Text
number :: Text
  , CreditCardNumberData -> Issuer
issuer :: Issuer
  }
  deriving (CreditCardNumberData -> CreditCardNumberData -> Bool
(CreditCardNumberData -> CreditCardNumberData -> Bool)
-> (CreditCardNumberData -> CreditCardNumberData -> Bool)
-> Eq CreditCardNumberData
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CreditCardNumberData -> CreditCardNumberData -> Bool
$c/= :: CreditCardNumberData -> CreditCardNumberData -> Bool
== :: CreditCardNumberData -> CreditCardNumberData -> Bool
$c== :: CreditCardNumberData -> CreditCardNumberData -> Bool
Eq, (forall x. CreditCardNumberData -> Rep CreditCardNumberData x)
-> (forall x. Rep CreditCardNumberData x -> CreditCardNumberData)
-> Generic CreditCardNumberData
forall x. Rep CreditCardNumberData x -> CreditCardNumberData
forall x. CreditCardNumberData -> Rep CreditCardNumberData x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep CreditCardNumberData x -> CreditCardNumberData
$cfrom :: forall x. CreditCardNumberData -> Rep CreditCardNumberData x
Generic, Int -> CreditCardNumberData -> Int
CreditCardNumberData -> Int
(Int -> CreditCardNumberData -> Int)
-> (CreditCardNumberData -> Int) -> Hashable CreditCardNumberData
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: CreditCardNumberData -> Int
$chash :: CreditCardNumberData -> Int
hashWithSalt :: Int -> CreditCardNumberData -> Int
$chashWithSalt :: Int -> CreditCardNumberData -> Int
Hashable, Eq CreditCardNumberData
Eq CreditCardNumberData
-> (CreditCardNumberData -> CreditCardNumberData -> Ordering)
-> (CreditCardNumberData -> CreditCardNumberData -> Bool)
-> (CreditCardNumberData -> CreditCardNumberData -> Bool)
-> (CreditCardNumberData -> CreditCardNumberData -> Bool)
-> (CreditCardNumberData -> CreditCardNumberData -> Bool)
-> (CreditCardNumberData
    -> CreditCardNumberData -> CreditCardNumberData)
-> (CreditCardNumberData
    -> CreditCardNumberData -> CreditCardNumberData)
-> Ord CreditCardNumberData
CreditCardNumberData -> CreditCardNumberData -> Bool
CreditCardNumberData -> CreditCardNumberData -> Ordering
CreditCardNumberData
-> CreditCardNumberData -> CreditCardNumberData
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: CreditCardNumberData
-> CreditCardNumberData -> CreditCardNumberData
$cmin :: CreditCardNumberData
-> CreditCardNumberData -> CreditCardNumberData
max :: CreditCardNumberData
-> CreditCardNumberData -> CreditCardNumberData
$cmax :: CreditCardNumberData
-> CreditCardNumberData -> CreditCardNumberData
>= :: CreditCardNumberData -> CreditCardNumberData -> Bool
$c>= :: CreditCardNumberData -> CreditCardNumberData -> Bool
> :: CreditCardNumberData -> CreditCardNumberData -> Bool
$c> :: CreditCardNumberData -> CreditCardNumberData -> Bool
<= :: CreditCardNumberData -> CreditCardNumberData -> Bool
$c<= :: CreditCardNumberData -> CreditCardNumberData -> Bool
< :: CreditCardNumberData -> CreditCardNumberData -> Bool
$c< :: CreditCardNumberData -> CreditCardNumberData -> Bool
compare :: CreditCardNumberData -> CreditCardNumberData -> Ordering
$ccompare :: CreditCardNumberData -> CreditCardNumberData -> Ordering
$cp1Ord :: Eq CreditCardNumberData
Ord, Int -> CreditCardNumberData -> ShowS
[CreditCardNumberData] -> ShowS
CreditCardNumberData -> String
(Int -> CreditCardNumberData -> ShowS)
-> (CreditCardNumberData -> String)
-> ([CreditCardNumberData] -> ShowS)
-> Show CreditCardNumberData
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CreditCardNumberData] -> ShowS
$cshowList :: [CreditCardNumberData] -> ShowS
show :: CreditCardNumberData -> String
$cshow :: CreditCardNumberData -> String
showsPrec :: Int -> CreditCardNumberData -> ShowS
$cshowsPrec :: Int -> CreditCardNumberData -> ShowS
Show, CreditCardNumberData -> ()
(CreditCardNumberData -> ()) -> NFData CreditCardNumberData
forall a. (a -> ()) -> NFData a
rnf :: CreditCardNumberData -> ()
$crnf :: CreditCardNumberData -> ()
NFData)

instance Resolve CreditCardNumberData where
  type ResolvedValue CreditCardNumberData = CreditCardNumberValue
  resolve :: Context
-> Options
-> CreditCardNumberData
-> Maybe (ResolvedValue CreditCardNumberData, Bool)
resolve Context
_ Options
_ CreditCardNumberData {Text
number :: Text
number :: CreditCardNumberData -> Text
number, Issuer
issuer :: Issuer
issuer :: CreditCardNumberData -> Issuer
issuer} =
    (CreditCardNumberValue, Bool)
-> Maybe (CreditCardNumberValue, Bool)
forall a. a -> Maybe a
Just (Text -> Issuer -> CreditCardNumberValue
CreditCardNumberValue Text
number Issuer
issuer, Bool
False)

data CreditCardNumberValue = CreditCardNumberValue
  { CreditCardNumberValue -> Text
vNumber :: Text
  , CreditCardNumberValue -> Issuer
vIssuer :: Issuer
  }
  deriving (CreditCardNumberValue -> CreditCardNumberValue -> Bool
(CreditCardNumberValue -> CreditCardNumberValue -> Bool)
-> (CreditCardNumberValue -> CreditCardNumberValue -> Bool)
-> Eq CreditCardNumberValue
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CreditCardNumberValue -> CreditCardNumberValue -> Bool
$c/= :: CreditCardNumberValue -> CreditCardNumberValue -> Bool
== :: CreditCardNumberValue -> CreditCardNumberValue -> Bool
$c== :: CreditCardNumberValue -> CreditCardNumberValue -> Bool
Eq, Eq CreditCardNumberValue
Eq CreditCardNumberValue
-> (CreditCardNumberValue -> CreditCardNumberValue -> Ordering)
-> (CreditCardNumberValue -> CreditCardNumberValue -> Bool)
-> (CreditCardNumberValue -> CreditCardNumberValue -> Bool)
-> (CreditCardNumberValue -> CreditCardNumberValue -> Bool)
-> (CreditCardNumberValue -> CreditCardNumberValue -> Bool)
-> (CreditCardNumberValue
    -> CreditCardNumberValue -> CreditCardNumberValue)
-> (CreditCardNumberValue
    -> CreditCardNumberValue -> CreditCardNumberValue)
-> Ord CreditCardNumberValue
CreditCardNumberValue -> CreditCardNumberValue -> Bool
CreditCardNumberValue -> CreditCardNumberValue -> Ordering
CreditCardNumberValue
-> CreditCardNumberValue -> CreditCardNumberValue
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: CreditCardNumberValue
-> CreditCardNumberValue -> CreditCardNumberValue
$cmin :: CreditCardNumberValue
-> CreditCardNumberValue -> CreditCardNumberValue
max :: CreditCardNumberValue
-> CreditCardNumberValue -> CreditCardNumberValue
$cmax :: CreditCardNumberValue
-> CreditCardNumberValue -> CreditCardNumberValue
>= :: CreditCardNumberValue -> CreditCardNumberValue -> Bool
$c>= :: CreditCardNumberValue -> CreditCardNumberValue -> Bool
> :: CreditCardNumberValue -> CreditCardNumberValue -> Bool
$c> :: CreditCardNumberValue -> CreditCardNumberValue -> Bool
<= :: CreditCardNumberValue -> CreditCardNumberValue -> Bool
$c<= :: CreditCardNumberValue -> CreditCardNumberValue -> Bool
< :: CreditCardNumberValue -> CreditCardNumberValue -> Bool
$c< :: CreditCardNumberValue -> CreditCardNumberValue -> Bool
compare :: CreditCardNumberValue -> CreditCardNumberValue -> Ordering
$ccompare :: CreditCardNumberValue -> CreditCardNumberValue -> Ordering
$cp1Ord :: Eq CreditCardNumberValue
Ord, Int -> CreditCardNumberValue -> ShowS
[CreditCardNumberValue] -> ShowS
CreditCardNumberValue -> String
(Int -> CreditCardNumberValue -> ShowS)
-> (CreditCardNumberValue -> String)
-> ([CreditCardNumberValue] -> ShowS)
-> Show CreditCardNumberValue
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CreditCardNumberValue] -> ShowS
$cshowList :: [CreditCardNumberValue] -> ShowS
show :: CreditCardNumberValue -> String
$cshow :: CreditCardNumberValue -> String
showsPrec :: Int -> CreditCardNumberValue -> ShowS
$cshowsPrec :: Int -> CreditCardNumberValue -> ShowS
Show)

instance ToJSON CreditCardNumberValue where
  toJSON :: CreditCardNumberValue -> Value
toJSON (CreditCardNumberValue Text
number Issuer
issuer) =
    [Pair] -> Value
object [ Text
"value" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Text
number
           , Text
"issuer" Text -> Issuer -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Issuer
issuer
           ]