{-# LANGUAGE TupleSections #-}

module Input.Download(downloadInput, DownloadInput(..)) where

import System.FilePath
import Control.Monad.Extra
import System.Directory
import Data.Conduit.Binary (sinkFile)
import qualified Network.HTTP.Conduit as C
import Network.Connection
import qualified Data.Conduit as C
import General.Util
import General.Timing
import Control.Monad.Trans.Resource
import Control.Exception.Extra

data DownloadInput =
    AlwaysDownloadInput
    | NeverDownloadInput
    | DownloadInputIfNotThere


-- | Download all the input files to input/
downloadInput :: Timing -> Bool -> DownloadInput -> FilePath -> String -> URL -> IO FilePath
downloadInput timing insecure download dir name url = do
    let file = dir </> "input-" ++ name
    exists <- doesFileExist file
    let act =
            timed timing ("Downloading " ++ url) $ do
                downloadFile insecure (file <.> "part") url
                renameFile (file <.> "part") file
    case download of
        NeverDownloadInput ->
            unless exists $
              errorIO $ "File is not already downloaded and --download=no given, downloading " ++ url ++ " to " ++ file
        AlwaysDownloadInput -> act
        DownloadInputIfNotThere ->
            unless exists act
    pure file

downloadFile :: Bool -> FilePath -> String -> IO ()
downloadFile insecure file url = do
    let request = C.parseRequest_ url
    manager <- C.newManager $ C.mkManagerSettings
      (TLSSettingsSimple {
        settingDisableCertificateValidation = insecure,
        settingDisableSession = False,
        settingUseServerName = False
      }) Nothing
    runResourceT $ do
        response <- C.http request manager
        C.runConduit $ C.responseBody response C..| sinkFile file
