module Puppet.JsonCatalog where
import Puppet.DSL.Types hiding (Value)
import Puppet.Interpreter.Types
import Puppet.Printers
import qualified Data.Text as T
import qualified Data.HashMap.Strict as HM
import qualified Data.Map as Map
import Data.Aeson
import qualified Data.Vector as V
import Data.Attoparsec.Number
import Text.Parsec.Pos
import qualified Data.ByteString.Lazy as BSL
prref = String . showRRef
mkJsonCatalog :: T.Text -> Integer -> FinalCatalog -> FinalCatalog -> EdgeMap -> Value
mkJsonCatalog nodename version cat exports edges = Object $ HM.fromList [("data",datahash), ("document_type", String "Catalog"), ("metadata", Object (HM.fromList [("api_version", Number 1)]))]
where
datahash = Object $ HM.fromList [ ("classes" , Array (V.fromList classes))
, ("edges" , Array (V.fromList ledges))
, ("environment", String "production")
, ("name" , String nodename)
, ("resources" , Array (V.fromList resources))
, ("tags" , Array V.empty)
, ("version" , Number (I version))
]
lcat = Map.toList cat
classes = map (String . snd . fst) . filter (\((k,_),_) -> k == "class") $ lcat
ledges = map (\(s,d) -> Object $ HM.fromList [("source", prref s),("target", prref d)] ) . filter (\i -> Map.member (fst i) cat && Map.member (snd i) cat) . Map.keys $ edges
resources = map (res2JSon False . snd) lcat
fakeResource :: (ResIdentifier, SourcePos) -> RResource
fakeResource ((t,n),p) = RResource 0 n t Map.empty [] [["fake"]] p
res2JSon :: Bool -> RResource -> Value
res2JSon isExported (RResource _ rn rt rp _ scopes rpos) = Object $ HM.fromList [ ("exported", Bool isExported)
, ("file", String (T.pack $ sourceName rpos))
, ("line", Number (fromIntegral (sourceLine rpos)))
, ("parameters", Object (HM.delete "EXPORTEDSOURCE" $ HM.fromList paramlist))
, ("tags", Array V.empty)
, ("title", String realtitle)
, ("type", String . capitalizeResType $ rt)
, "scope" .= scopes
]
where
realtitle = if rt == "class"
then capitalizeResType ctitle
else ctitle
ctitle = case Map.lookup "title" rp of
Just (ResolvedString s) -> s
_ -> rn
paramlist = map (\(k,v) -> (k, rv2json v)) $ Map.toList $ Map.delete "title" rp
rv2json :: ResolvedValue -> Value
rv2json (ResolvedString x) = String x
rv2json (ResolvedRegexp x) = String x
rv2json (ResolvedInt x) = Number (I x)
rv2json (ResolvedDouble x) = Number (D x)
rv2json (ResolvedBool x) = Bool x
rv2json (ResolvedArray h) = Array (V.fromList (map rv2json h))
rv2json (ResolvedHash h) = Object $ HM.fromList $ map (\(k,v) -> (k, rv2json v)) h
rv2json _ = Null
catalog2JSon :: T.Text -> Integer -> FinalCatalog -> FinalCatalog -> EdgeMap -> BSL.ByteString
catalog2JSon nodename version dc de dm = encode (mkJsonCatalog nodename version dc de dm)