module CfnFlip.IntrinsicFunction
  ( getIntrinsicFunction
  , setIntrinsicFunction
  , fromIntrinsicFunction
  ) where

import CfnFlip.Prelude

import CfnFlip.Libyaml (Event(..), Tag(..))

-- | If an 'Event' is using a known @"!X"@, returns the @"Fn::Y"@ for it
getIntrinsicFunction :: Event -> Maybe ByteString
getIntrinsicFunction :: Event -> Maybe ByteString
getIntrinsicFunction = \case
  EventScalar ByteString
_ (UriTag String
t) Style
_ Anchor
_ -> forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup String
t [(String, ByteString)]
intrinsics
  EventMappingStart (UriTag String
t) MappingStyle
_ Anchor
_ -> forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup String
t [(String, ByteString)]
intrinsics
  EventSequenceStart (UriTag String
t) SequenceStyle
_ Anchor
_ -> forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup String
t [(String, ByteString)]
intrinsics
  Event
_ -> forall a. Maybe a
Nothing

-- | Set an 'Event' up with a @'UriTag' "!X"@
setIntrinsicFunction :: String -> Event -> Event
setIntrinsicFunction :: String -> Event -> Event
setIntrinsicFunction String
tag Event
e = forall a. a -> Maybe a -> a
fromMaybe Event
e forall a b. (a -> b) -> a -> b
$ do
  let t :: Tag
t = String -> Tag
UriTag String
tag

  case Event
e of
    EventScalar ByteString
x Tag
_ Style
y Anchor
z -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ ByteString -> Tag -> Style -> Anchor -> Event
EventScalar ByteString
x Tag
t Style
y Anchor
z
    EventMappingStart Tag
_ MappingStyle
x Anchor
y -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Tag -> MappingStyle -> Anchor -> Event
EventMappingStart Tag
t MappingStyle
x Anchor
y
    EventSequenceStart Tag
_ SequenceStyle
x Anchor
y -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Tag -> SequenceStyle -> Anchor -> Event
EventSequenceStart Tag
t SequenceStyle
x Anchor
y
    Event
_ -> forall a. Maybe a
Nothing

fromIntrinsicFunction :: Event -> Maybe String
fromIntrinsicFunction :: Event -> Anchor
fromIntrinsicFunction = \case
  EventScalar ByteString
x Tag
_ Style
_ Anchor
_ -> forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup ByteString
x [(ByteString, String)]
swappedIntrinsics
  Event
_ -> forall a. Maybe a
Nothing

intrinsics :: [(String, ByteString)]
intrinsics :: [(String, ByteString)]
intrinsics = forall a b. (a -> b) -> [a] -> [b]
map
  Text -> (String, ByteString)
toFn
  [ Text
"And"
  , Text
"Base64"
  , Text
"Cidr"
  , Text
"Equals"
  , Text
"FindInMap"
  , Text
"GetAtt"
  , Text
"GetAZs"
  , Text
"If"
  , Text
"ImportValue"
  , Text
"Join"
  , Text
"Not"
  , Text
"Or"
  , Text
"Ref"
  , Text
"Select"
  , Text
"Split"
  , Text
"Sub"
  , Text
"Transform"
  ]
 where
  toFn :: Text -> (String, ByteString)
toFn Text
x
    | Text
x forall a. Eq a => a -> a -> Bool
== Text
"Ref" = (String
"!" forall a. Semigroup a => a -> a -> a
<> Text -> String
unpack Text
x, Text -> ByteString
encodeUtf8 Text
x)
    | Bool
otherwise = (String
"!" forall a. Semigroup a => a -> a -> a
<> Text -> String
unpack Text
x, ByteString
"Fn::" forall a. Semigroup a => a -> a -> a
<> Text -> ByteString
encodeUtf8 Text
x)

swappedIntrinsics :: [(ByteString, String)]
swappedIntrinsics :: [(ByteString, String)]
swappedIntrinsics = forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> (b, a)
swap [(String, ByteString)]
intrinsics
 where
  swap :: (a, b) -> (b, a)
  swap :: forall a b. (a, b) -> (b, a)
swap (a
a, b
b) = (b
b, a
a)