{-# LANGUAGE NoImplicitPrelude #-}

-- | Description : mostly reversible conversion between ipynb and lhs
module IHaskell.Convert (convert) where

import           IHaskellPrelude

import           Data.Functor.Identity (Identity(Identity))
import           IHaskell.Convert.Args (ConvertSpec(..), fromJustConvertSpec, toConvertSpec)
import           IHaskell.Convert.IpynbToLhs (ipynbToLhs)
import           IHaskell.Convert.LhsToIpynb (lhsToIpynb)
import           IHaskell.Flags (Argument)
import           System.Directory (doesFileExist)

-- | used by @IHaskell convert@
convert :: [Argument] -> IO ()
convert :: [Argument] -> IO ()
convert [Argument]
args =
  case ConvertSpec Maybe -> ConvertSpec Identity
fromJustConvertSpec ([Argument] -> ConvertSpec Maybe
toConvertSpec [Argument]
args) of
    ConvertSpec
      { convertToIpynb :: forall (f :: * -> *). ConvertSpec f -> f Bool
convertToIpynb = Identity Bool
toIpynb
      , convertInput :: forall (f :: * -> *). ConvertSpec f -> f FilePath
convertInput = Identity FilePath
inputFile
      , convertOutput :: forall (f :: * -> *). ConvertSpec f -> f FilePath
convertOutput = Identity FilePath
outputFile
      , convertLhsStyle :: forall (f :: * -> *). ConvertSpec f -> f (LhsStyle Text)
convertLhsStyle = Identity LhsStyle Text
lhsStyle
      , convertOverwriteFiles :: forall (f :: * -> *). ConvertSpec f -> Bool
convertOverwriteFiles = Bool
force
      }
      | Bool
toIpynb -> do
          forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
force (FilePath -> IO ()
failIfExists FilePath
outputFile)
          LhsStyle Text -> FilePath -> FilePath -> IO ()
lhsToIpynb LhsStyle Text
lhsStyle FilePath
inputFile FilePath
outputFile
      | Bool
otherwise -> do
          forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
force (FilePath -> IO ()
failIfExists FilePath
outputFile)
          LhsStyle Text -> FilePath -> FilePath -> IO ()
ipynbToLhs LhsStyle Text
lhsStyle FilePath
inputFile FilePath
outputFile

-- | Call fail when the named file already exists.
failIfExists :: FilePath -> IO ()
failIfExists :: FilePath -> IO ()
failIfExists FilePath
file = do
  Bool
exists <- FilePath -> IO Bool
doesFileExist FilePath
file
  forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
exists forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadFail m => FilePath -> m a
fail forall a b. (a -> b) -> a -> b
$
    forall r. PrintfType r => FilePath -> r
printf FilePath
"File %s already exists. To force supply --force." FilePath
file