{-# LANGUAGE
    DataKinds
  , FlexibleContexts
  , OverloadedStrings
  , TemplateHaskell
  , PackageImports
  #-}

module Test.KeyValue where

import Prelude hiding (lines)
import Test.Common
import Test.Instances ()
import Test.Types

import Pipes.KeyValueCsv.Common
import Pipes.KeyValueCsv.KeyValue
import Pipes.KeyValueCsv.Types
import Data.Validation

import Control.Lens hiding (Const)
import qualified Data.Functor.Identity as Transformers
import Data.Default.Class
import Data.List hiding (lines)
import Data.Monoid
import qualified Data.Text as Text
import Data.Text.Lazy.Builder
import Data.Reflection
import Data.Vinyl
import Data.Vinyl.Functor
import Data.Vinyl.Utils.Compose
import Test.QuickCheck
import qualified Pipes.Prelude as Pipes
import Pipes.Text (fromLazy)

delim :: Char
delim = ','

type TestFields = '[Int, Alphabetic, Quoted]

prop_read :: Rec Id TestFields -> Property
prop_read r = pure r === useDelimiter delim parsed
    & counterexample (concatMap Text.unpack $ Pipes.toList pipe)
  where
    names :: Rec (Const Text) TestFields
    names = Const "foo" :& Const "bar" :& Const "baz" :& RNil
    pipe :: Producer Text Transformers.Identity ()
    pipe = 
        fromLazy 
      . toLazyText 
      . mconcat 
      . intersperse (singleton '\n')
      . zipWith keyValue (map fromText $ recordToList names) 
      $ build r
    keyValue k v = k <> singleton delim <> v
    parsed :: Given Delimiter => Validation [KeyValueError] (Rec Id TestFields)
    parsed =
        rtraverse1
      . fst
      . Transformers.runIdentity
      . parseKeyValues (def & keyNames .~ names)
      $ lines pipe

return []

test :: IO Bool
test = $quickCheckAll

