module Reddit.Types.CommentSpec where

import Reddit.Types.Comment
import Reddit.Types.Listing
import Reddit.Types.Subreddit hiding (subredditID)
import Reddit.Types.User

import Control.Monad
import Data.ByteString.Lazy (ByteString)
import Data.Maybe
import Data.Time.Clock
import Data.Aeson (eitherDecode)
import Test.Hspec
import qualified Data.ByteString.Lazy.Char8 as ByteString
import qualified Data.Text as Text

isRight :: Either a b -> Bool
isRight = const False `either` const True

isLeft :: Either a b -> Bool
isLeft = const True `either` const False

main :: IO ()
main = hspec spec

spec :: Spec
spec = describe "Reddit.Types.Comment" $ do
  let decode' = eitherDecode :: ByteString -> Either String CommentID
  getUserCommentsExample <- runIO $ ByteString.readFile "test/data/getUserComments_example.json"
  time <- runIO getCurrentTime

  it "can read the example" $
    getUserCommentsExample `shouldSatisfy` not . ByteString.null

  it "can parse a list of comments from json" $ do
    let decoded = eitherDecode getUserCommentsExample :: Either String CommentListing
    decoded `shouldSatisfy` isRight

    case decoded of
      Left _ -> expectationFailure "json parse failed"
      Right (Listing b a cs) -> do
        cs `shouldSatisfy` not . null
        b `shouldBe` Nothing
        a `shouldSatisfy` isJust

        length cs `shouldBe` 5
        forM_ cs $ \c -> do
          author c `shouldBe` Username "Intolerable"
          score c `shouldSatisfy` isJust
          subreddit c `shouldBe` R "DotA2"
          subredditID c `shouldBe` SubredditID "2s580"
          authorFlairText c `shouldBe` Just "sneep sneep"
          authorFlairCSSClass c `shouldBe` Just "rapier"
          body c `shouldSatisfy` not . Text.null
          bodyHTML c `shouldSatisfy` not . Text.null
          replies c `shouldBe` Listing Nothing Nothing []
          created c `shouldSatisfy` (< time)

  it "can parse a CommentID" $ do
    decode' "\"t1_cl1royq\"" `shouldBe` Right (CommentID "cl1royq")
    decode' "\"cl1royq\"" `shouldBe` Right (CommentID "cl1royq")
    decode' "\"t5_2s580\"" `shouldSatisfy` isLeft
