{-# LANGUAGE OverloadedStrings #-} module Eventlog.Trie where import Prelude hiding (init, lookup) import Data.Text (Text, pack) import Eventlog.Types import Data.Word import qualified Data.Map as Map import Data.Map ((!)) import qualified Data.Trie.Map as Trie import qualified Data.Trie.Map.Internal as TrieI import Data.Aeson import Control.Monad.State outputTree :: Map.Map Word32 CostCentre -> [(Bucket, (Int, BucketInfo))] -> Value outputTree ccMap mdescs = let t = Trie.fromList [(k, (i, b, v)) | (Bucket b, (i, BucketInfo { shortDescription = v , longDescription = (Just k) })) <- mdescs ] in toJSON $ outputTrie ccMap t outputTrie :: Map.Map Word32 CostCentre -> Trie.TMap Word32 (Int, Text, Text) -> [Value] outputTrie ccMap (TrieI.TMap (TrieI.Node ni m)) = mkNode "TOP" Nothing "MAIN" ni : flip evalState 0 (outputTrieLoop ccMap "TOP" m) newLabel :: Word32 -> State Int Text newLabel n = do l <- get modify (+1) return (pack (show l ++ "-" ++ show n)) outputTrieLoop :: Map.Map Word32 CostCentre -> Text -> Map.Map Word32 (Trie.TMap Word32 (Int, Text, Text)) -> State Int [Value] outputTrieLoop ccMap p cs = let go p' (TrieI.TMap (TrieI.Node mv cs')) rest = do nid <- newLabel p' let n = mkNode nid (Just p) (label $ ccMap ! p') mv rs <- outputTrieLoop ccMap nid cs' os <- rest return (n : rs ++ os) in Map.foldrWithKey go (return []) cs mkNode :: Text -> Maybe Text -> Text -> Maybe (Int, Text, Text) -> Value mkNode id_string mparent n mccs = object $ [ "id" .= id_string, "name" .= n , "ccs" .= maybe "" (\(_, v, _) -> v) mccs , "c" .= maybe "OTHER" (\(_, _, c) -> c) mccs] ++ ["parent" .= p | Just p <- [mparent] ]