{-| Dictionary IO functions.

module Shikensu.Contrib.IO
    ( Shikensu.Contrib.IO.read
    , Shikensu.Contrib.IO.readDef
    , Shikensu.Contrib.IO.write
    , Shikensu.Contrib.IO.writeDef
    ) where

import Data.Maybe (fromMaybe)
import Shikensu.Internal.Types
import System.Directory (createDirectoryIfMissing, doesFileExist)
import System.FilePath (FilePath, joinPath, takeDirectory)

import qualified Data.ByteString as B (empty, readFile, writeFile)
import qualified Shikensu.Utilities as Utilities (mapIO)

{-| Read.

Read the contents of each file, and for each file (ie. definition)
put that content in the `content` property.
read :: Dictionary -> IO Dictionary
read =
    Utilities.mapIO readDef

readDef :: Definition -> IO Definition
readDef def =
        absPath = absolutePath def
        doesFileExist absPath >>= \exists ->
            if exists then
                    (\c -> def { content = Just c })
                    (B.readFile absPath)
                    def { content = Nothing }

{-| Write.

Write the contents of each definition to a file.
The path of the new file is `joinPath [rootDirname, givenDirectoryName, localPath]`.
write :: FilePath -> Dictionary -> IO Dictionary
write dest =
    Utilities.mapIO (writeDef dest)

writeDef :: FilePath -> Definition -> IO Definition
writeDef dest def =
        path = joinPath [rootDirname def, dest, localPath def]
        cont = fromMaybe B.empty (content def)
        createDirectoryIfMissing True (takeDirectory path)
            >> B.writeFile path cont
            >> return def