content: {-# LANGUAGE CPP #-}
  
  import ProjectM36.Base
  import ProjectM36.Relation.Show.CSV
  import ProjectM36.Relation.Parse.CSV
  import qualified ProjectM36.Attribute as A
  import ProjectM36.Relation
  import ProjectM36.DataTypes.Basic
  import ProjectM36.DataTypes.List
  import ProjectM36.DataTypes.Interval
  
  import System.Exit
  import Test.HUnit
  import Data.Time.Calendar
  import Data.Time.Clock
  
  #if __GLASGOW_HASKELL__ < 804
  import Data.Monoid
  #endif
  
  {-
  import qualified Data.Text.Lazy as TL
  import qualified Data.Text.Lazy.Encoding as TE
  import ProjectM36.Relation.Show.Term
  import qualified Data.ByteString.Lazy as BS
  -}
  
  main :: IO ()
  main = do
    tcounts <- runTestTT $ TestList [testCSVExport,
                                     testADTExport]
    if errors tcounts + failures tcounts > 0 then exitFailure else exitSuccess
  
  assertEither :: (Show a) => IO (Either a b) -> IO b
  assertEither x = do
    res <- x
    case res of
      Left err -> assertFailure (show err) >> undefined
      Right val -> pure val
  
  testADTExport :: Test
  testADTExport = TestCase $ do
    let adtCSV = "a\nCons 4 (Cons 5 Empty)\n"
        attrs = A.attributesFromList [Attribute "a" (listAtomType IntegerAtomType)]
        expectedRel = mkRelationFromList attrs [[listCons IntegerAtomType [IntegerAtom 4, IntegerAtom 5]]]
    case csvAsRelation attrs basicTypeConstructorMapping adtCSV of
      Left err -> assertFailure ("import failure: " <> show err)
      Right rel -> assertEqual "import cons list" expectedRel (Right rel)
  
  --round-trip various atom types through CSV export/import
  testCSVExport :: Test
  testCSVExport = TestCase $ do
    now <- getCurrentTime
    testInterval <- assertEither $ pure (createInterval
                                  (DateTimeAtom now)
                                  (DateTimeAtom (addUTCTime 86400 now))
                                  True
                                  False)
    let attrs = A.attributesFromList [Attribute "textattr" TextAtomType,
                                      Attribute "integerattr" IntegerAtomType,
                                      Attribute "dayattr" DayAtomType,
                                      Attribute "datetimeattr" DateTimeAtomType,
                                      Attribute "bytestringattr" ByteStringAtomType,
                                      Attribute "listintegerattr" (listAtomType IntegerAtomType),
                                      Attribute "listtextattr" (listAtomType TextAtomType),
                                      Attribute "intervalattr" (intervalAtomType DateTimeAtomType)
                                     ]
        sampleByteString = "\1\0\244\34\150"
        relOrErr = mkRelationFromList attrs [
          [TextAtom "text atom with \"quote\"",
           IntegerAtom 123,
           DayAtom (fromGregorian 2017 4 10),
           DateTimeAtom now,
           ByteStringAtom sampleByteString,
           listCons IntegerAtomType [IntegerAtom 5, IntegerAtom 6, IntegerAtom 7],
           listCons TextAtomType [TextAtom "text1", TextAtom "text2"],
           testInterval
           ],
          [TextAtom "second text atom with 漢字",
           IntegerAtom 314,
           DayAtom (fromGregorian 1001 6 28),
           DateTimeAtom (addUTCTime 360 now),
           ByteStringAtom sampleByteString,
           listCons IntegerAtomType [IntegerAtom 10, IntegerAtom 11, IntegerAtom 12],
           listCons TextAtomType [TextAtom "text5\"", TextAtom "text6\r\n"],
           testInterval
          ]]
  
    case relOrErr of
      Left err -> assertFailure $ "export relation creation failure: " ++ show err
      Right rel ->
        case relationAsCSV rel of
          Left err -> assertFailure $ "export failed: " ++ show err
          Right csvData ->
            --BS.writeFile "/tmp/csv" csvData
            --putStrLn (TL.unpack (TE.decodeUtf8 csvData))
            case csvAsRelation attrs basicTypeConstructorMapping csvData of -- import csv data back to relation
              Left err -> assertFailure $ "re-import failed: " ++ show err
              Right rel' -> assertEqual "relation CSV comparison" rel rel'
  