{-# LANGUAGE OverloadedStrings #-}

import Text.DocTemplates
import Test.Hspec
import Data.Text
import Data.Aeson

data Employee = Employee { firstName :: String
                         , lastName  :: String
                         , salary    :: Maybe Integer }
instance ToJSON Employee where
  toJSON e = object [ "name" .= object [ "first" .= firstName e
                                       , "last"  .= lastName e ]
                    , "salary" .= salary e ]

employees :: [Employee]
employees = [ Employee "John" "Doe" Nothing
            , Employee "Omar" "Smith" (Just 30000)
            , Employee "Sara" "Chen" (Just 60000) ]

template :: Text
template =
  "$for(employee)$Hi, $employee.name.first$. $if(employee.salary)$You make $$$employee.salary$.$else$No salary data.$endif$$sep$\n$endfor$"

main :: IO ()
main = hspec $ do
  describe "applyTemplate" $ do
    it "works" $ do
      applyTemplate template (object ["employee" .= employees])
        `shouldBe`
        (Right "Hi, John. No salary data.\nHi, Omar. You make $30000.\nHi, Sara. You make $60000." :: Either String Text)
    it "renders numbers appropriately as integer or floating" $ do
      applyTemplate "$m$ and $n$"
        (object ["m" .= (5 :: Integer), "n" .= (7.3 :: Double)])
        `shouldBe`
        (Right "5 and 7.3" :: Either String Text)
    it "handles comments" $ do
      applyTemplate "hello $--there and $m$\n$-- comment\nbar"
        (object ["m" .= (5 :: Integer)])
        `shouldBe`
        (Right "hello \nbar" :: Either String Text)
    it "fails with an incorrect template" $ do
      applyTemplate "$if(x$and$endif$" (object [])
        `shouldBe`
        (Left "\"template\" (line 1, column 6):\nunexpected \"$\"\nexpecting \".\" or \")$\"" :: Either String Text)

