module CfnFlip.YamlToJson
  ( InvalidYamlEvent(..)
  , translate
  ) where

import CfnFlip.Prelude

import CfnFlip.Conduit
import CfnFlip.IntrinsicFunction
import CfnFlip.Libyaml
import qualified Data.ByteString as BS
import qualified Prelude as Unsafe (toEnum)

translate :: MonadIO m => ConduitT Event Event m ()
translate :: forall (m :: * -> *). MonadIO m => ConduitT Event Event m ()
translate = forall (m :: * -> *) i o r.
Monad m =>
(i -> ConduitT i o m r) -> ConduitT i o m ()
awaitForever forall a b. (a -> b) -> a -> b
$ \case
  e :: Event
e@(EventScalar ByteString
x (UriTag String
"!GetAtt") Style
_ Anchor
_) -> do
    (ByteString
resource, ByteString
attribute) <- forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (m :: * -> *) a. MonadIO m => Event -> ByteString -> m a
throwInvalidGetAtt Event
e ByteString
x) forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ ByteString -> Maybe (ByteString, ByteString)
parseGetAtt ByteString
x

    forall (m :: * -> *) i.
Monad m =>
ByteString -> ConduitT i Event m () -> ConduitT i Event m ()
makeMapping ByteString
"Fn::GetAtt" forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) i.
Monad m =>
ConduitT i Event m () -> ConduitT i Event m ()
makeSequence forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) mono i.
(Monad m, MonoFoldable mono) =>
mono -> ConduitT i (Element mono) m ()
yieldMany
      [ ByteString -> Tag -> Style -> Anchor -> Event
EventScalar ByteString
resource Tag
NoTag Style
Plain forall a. Maybe a
Nothing
      , ByteString -> Tag -> Style -> Anchor -> Event
EventScalar ByteString
attribute Tag
NoTag Style
Plain forall a. Maybe a
Nothing
      ]

  Event
e | Just ByteString
tag <- Event -> Maybe ByteString
getIntrinsicFunction Event
e -> do
    forall (m :: * -> *) i.
Monad m =>
ByteString -> ConduitT i Event m () -> ConduitT i Event m ()
makeMapping ByteString
tag forall a b. (a -> b) -> a -> b
$ do
      forall (m :: * -> *) o i. Monad m => o -> ConduitT i o m ()
yield Event
e
      forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Event -> Bool
startsMapOrSequence Event
e) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). Monad m => Event -> ConduitT Event Event m ()
takeMapOrSequenceC Event
e forall (m :: * -> *) a b c r.
Monad m =>
ConduitT a b m () -> ConduitT b c m r -> ConduitT a c m r
.| forall (m :: * -> *). MonadIO m => ConduitT Event Event m ()
translate

  Event
e -> forall (m :: * -> *) o i. Monad m => o -> ConduitT i o m ()
yield Event
e

parseGetAtt :: ByteString -> Maybe (ByteString, ByteString)
parseGetAtt :: ByteString -> Maybe (ByteString, ByteString)
parseGetAtt ByteString
x = case Word8 -> ByteString -> [ByteString]
BS.split (Char -> Word8
charToWord8 Char
'.') ByteString
x of
  [ByteString
resource, ByteString
attribute] -> forall a. a -> Maybe a
Just (ByteString
resource, ByteString
attribute)
  [ByteString]
_ -> forall a. Maybe a
Nothing

throwInvalidGetAtt :: MonadIO m => Event -> ByteString -> m a
throwInvalidGetAtt :: forall (m :: * -> *) a. MonadIO m => Event -> ByteString -> m a
throwInvalidGetAtt Event
e ByteString
x =
  forall (m :: * -> *) e a. (MonadIO m, Exception e) => e -> m a
throwIO
    forall a b. (a -> b) -> a -> b
$ Event -> String -> InvalidYamlEvent
InvalidYamlEvent Event
e
    forall a b. (a -> b) -> a -> b
$ String
"!GetAtt shoule be \"Resource.Attribute\", saw "
    forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show ByteString
x

charToWord8 :: Char -> Word8
charToWord8 :: Char -> Word8
charToWord8 = forall a. Enum a => Int -> a
Unsafe.toEnum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Enum a => a -> Int
fromEnum