-- | The TempFile module allocates temporary files
module Util.TempFile(
   newTempFile, -- :: IO FilePath
   ) where


import System.Directory

import Control.Concurrent
import System.IO.Unsafe

import Util.IOExtras
import Util.WBFiles
import Util.UniqueFile
import Util.FileNames

data TempFileSource = TempFileSource {
   TempFileSource -> UniqueFileStore
fileStore :: UniqueFileStore,
   TempFileSource -> MVar UniqueFileCounter
fileSource :: MVar UniqueFileCounter
   }

tempFileSource :: TempFileSource
tempFileSource :: TempFileSource
tempFileSource = IO TempFileSource -> TempFileSource
forall a. IO a -> a
unsafePerformIO (
   do
      String
workingDir <- IO String
getWorkingDir
      let directory :: String
directory = String -> String -> String
combineNames String
workingDir String
"#"
      IO () -> IO (Maybe ())
forall a. IO a -> IO (Maybe a)
catchAlreadyExists (String -> IO ()
createDirectory String
workingDir)
      IO () -> IO (Maybe ())
forall a. IO a -> IO (Maybe a)
catchAlreadyExists (String -> IO ()
createDirectory String
directory)
      UniqueFileStore
fileStore <- String -> (String -> IO ()) -> IO UniqueFileStore
newUniqueFileStore String
directory String -> IO ()
createDirectory
      MVar UniqueFileCounter
fileSource <- UniqueFileCounter -> IO (MVar UniqueFileCounter)
forall a. a -> IO (MVar a)
newMVar UniqueFileCounter
initialUniqueFileCounter
      TempFileSource -> IO TempFileSource
forall (m :: * -> *) a. Monad m => a -> m a
return (TempFileSource :: UniqueFileStore -> MVar UniqueFileCounter -> TempFileSource
TempFileSource {fileStore :: UniqueFileStore
fileStore = UniqueFileStore
fileStore,fileSource :: MVar UniqueFileCounter
fileSource = MVar UniqueFileCounter
fileSource})
   )
{-# NOINLINE tempFileSource #-}

newTempFile :: IO FilePath
newTempFile :: IO String
newTempFile =
   do
      let
         TempFileSource {fileStore :: TempFileSource -> UniqueFileStore
fileStore = UniqueFileStore
fileStore,fileSource :: TempFileSource -> MVar UniqueFileCounter
fileSource = MVar UniqueFileCounter
fileSource} =
            TempFileSource
tempFileSource
      UniqueFileCounter
fileCounter <- MVar UniqueFileCounter -> IO UniqueFileCounter
forall a. MVar a -> IO a
takeMVar MVar UniqueFileCounter
fileSource
      let (String
newName,UniqueFileCounter
nextFileCounter) = UniqueFileCounter -> (String, UniqueFileCounter)
stepUniqueFileCounter UniqueFileCounter
fileCounter
      MVar UniqueFileCounter -> UniqueFileCounter -> IO ()
forall a. MVar a -> a -> IO ()
putMVar MVar UniqueFileCounter
fileSource UniqueFileCounter
nextFileCounter
      UniqueFileStore -> String -> IO ()
ensureDirectories UniqueFileStore
fileStore String
newName
      String -> IO String
forall (m :: * -> *) a. Monad m => a -> m a
return (UniqueFileStore -> String -> String
getFilePath UniqueFileStore
fileStore String
newName)