module Simplex.FileTransfer.Util
  ( uniqueCombine,
    removePath,
  )
where

import Simplex.Messaging.Util (ifM, whenM)
import System.FilePath (splitExtensions, (</>))
import UnliftIO
import UnliftIO.Directory

uniqueCombine :: MonadIO m => FilePath -> String -> m FilePath
uniqueCombine :: forall (m :: * -> *).
MonadIO m =>
FilePath -> FilePath -> m FilePath
uniqueCombine FilePath
filePath FilePath
fileName = Int -> m FilePath
forall {m :: * -> *} {a}.
(MonadIO m, Eq a, Num a, Show a) =>
a -> m FilePath
tryCombine (Int
0 :: Int)
  where
    tryCombine :: a -> m FilePath
tryCombine a
n =
      let (FilePath
name, FilePath
ext) = FilePath -> (FilePath, FilePath)
splitExtensions FilePath
fileName
          suffix :: FilePath
suffix = if a
n a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0 then FilePath
"" else FilePath
"_" FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> a -> FilePath
forall a. Show a => a -> FilePath
show a
n
          f :: FilePath
f = FilePath
filePath FilePath -> FilePath -> FilePath
</> (FilePath
name FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath
suffix FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath
ext)
       in m Bool -> m FilePath -> m FilePath -> m FilePath
forall (m :: * -> *) a. Monad m => m Bool -> m a -> m a -> m a
ifM (FilePath -> m Bool
forall (m :: * -> *). MonadIO m => FilePath -> m Bool
doesPathExist FilePath
f) (a -> m FilePath
tryCombine (a -> m FilePath) -> a -> m FilePath
forall a b. (a -> b) -> a -> b
$ a
n a -> a -> a
forall a. Num a => a -> a -> a
+ a
1) (FilePath -> m FilePath
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure FilePath
f)

removePath :: MonadIO m => FilePath -> m ()
removePath :: forall (m :: * -> *). MonadIO m => FilePath -> m ()
removePath FilePath
p = do
  m Bool -> m () -> m () -> m ()
forall (m :: * -> *) a. Monad m => m Bool -> m a -> m a -> m a
ifM (FilePath -> m Bool
forall (m :: * -> *). MonadIO m => FilePath -> m Bool
doesDirectoryExist FilePath
p) (FilePath -> m ()
forall (m :: * -> *). MonadIO m => FilePath -> m ()
removeDirectoryRecursive FilePath
p) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
    m Bool -> m () -> m ()
forall (m :: * -> *). Monad m => m Bool -> m () -> m ()
whenM (FilePath -> m Bool
forall (m :: * -> *). MonadIO m => FilePath -> m Bool
doesFileExist FilePath
p) (FilePath -> m ()
forall (m :: * -> *). MonadIO m => FilePath -> m ()
removeFile FilePath
p)