{-# OPTIONS_GHC -Wno-deferred-out-of-scope-variables #-}
module Main where

import qualified Data.Map.Strict as Map
import Huffman
import Test.HUnit
import Auxiliaries (Bit (..))

type CodingTable = Map.Map Char [Bit]

test_isConsistent :: IO ()
test_isConsistent = do
  assertEqual "test1_Valid_tree" True (isConsistent exercise1TreeValid)
  assertEqual "test2_Invalid_tree" False (isConsistent exercise1TreeInvalid)

test_toCodingTable :: IO ()
test_toCodingTable = do
  assertEqual "test1_ValidTree" treeValidCodingTable (toCodingTable exercise1TreeValid)
  assertEqual "test2_OneLeaf" treeOnlyLeafCodingTable (toCodingTable (Root (Leaf 'A' 2)))

test_encode :: IO ()
test_encode = do
  assertEqual "test encode ENTE" enteEncoded (encode codingTableForTesting "ENTE")
  assertEqual "test encode ENTE" erenEncoded (encode codingTableForTesting "EREN")
  assertEqual "test encode START" startEncoded (encode codingTableForTesting "START")
  assertEqual "test encode RAIN" rainEncoded (encode codingTableForTesting "RAIN")

test_decode :: IO ()
test_decode = do
  assertEqual "test decode Ente" "ENTE" (decode exercise1TreeValid (encode codingTableForTesting "ENTE"))
  assertEqual "test decode Eren" "EREN" (decode exercise1TreeValid (encode codingTableForTesting "EREN"))
  assertEqual "test decode Start" "START" (decode exercise1TreeValid (encode codingTableForTesting "START"))
  assertEqual "test decode Rain" "RAIN" (decode exercise1TreeValid (encode codingTableForTesting "RAIN"))

test_buildHTree :: IO ()
test_buildHTree = do
  assertEqual "test buildHTree" treeMISSISSIPPI (buildHTree "MISSISSIPPI")
  assertEqual "test buildHTree" treeAaron (buildHTree "Aaron")
  assertEqual "test buildHTree" treeAAABC (buildHTree "AAABC")
  assertEqual "test buildHTree" (Root (Leaf 'A' 0)) (buildHTree "")
  assertEqual "test buildHTree" (Root (Leaf 'A' 1)) (buildHTree "A")

test_toDecodeTree :: IO ()
test_toDecodeTree = do
  assertEqual "test toDecodeTree" testCodingTableHTree (toDecodeTree testCodingTable)

test_toFromWord8 :: IO ()
test_toFromWord8 = pure ()

test_encodeDecodeFile :: IO ()
test_encodeDecodeFile = do
  _ <- encodeFile "Aaron.txt" "Aaron.comp"
  decodeFile "Aaron.comp" "Aaron2.txt"

allTests :: Test
allTests =
  TestList
    [ mkTest "toCodingTable" test_toCodingTable
    , mkTest "encode" test_encode
    , mkTest "isConsistent" test_isConsistent
    , mkTest "decode" test_decode
    , mkTest "buildHTree" test_buildHTree
    , mkTest "toDecodeTree" test_toDecodeTree
    , mkTest "toFromWord8" test_toFromWord8
    , mkTest "encodeDecodeFile" test_encodeDecodeFile
    ]
  where
    mkTest label ass = TestLabel label (TestCase ass)

main :: IO ()
main = runTestTTAndExit allTests
