module Main where

import qualified Data.Aeson as J
import qualified Data.ByteString.Lazy as BS
import qualified Data.ByteString.Lazy.Char8 as BS8
import qualified Data.Eben as E
import qualified Data.HashMap.Strict as HM
import qualified Data.Map.Strict as M
import           Data.Scientific (floatingOrInteger)
import qualified Data.Vector as V
import           Data.Text.Encoding (encodeUtf8)

convert :: J.Value -> Either String E.Value
convert (J.Array as)  =
  (E.List . V.toList) `fmap` traverse convert as
convert (J.Object os) =
  (E.Dict . M.fromList) `fmap` sequence
    [ sequence (encodeUtf8 k, convert v)
    | (k, v) <- HM.toList os
    ]
convert (J.String ts) = pure (E.String (encodeUtf8 ts))
convert (J.Number n)  = case floatingOrInteger n of
  Left f  -> pure (E.Float f)
  Right i -> pure (E.Integer i)
convert (J.Bool _)    = Left "No Eben repr for bool"
convert J.Null        = Left "No Eben repr for null"

main :: IO ()
main = do
  cs <- BS.getContents
  case J.decode cs of
    Nothing -> putStrLn "Not valid JSON"
    Just vs -> case convert vs of
      Left err -> putStrLn err
      Right eb -> BS8.putStrLn (E.encode eb)
