{-|
Module: IHP.FileStorage.Types
Copyright: (c) digitally induced GmbH, 2021
-}
module IHP.FileStorage.Types
( FileStorage (..)
, StoredFile (..)
, StoreFileOptions (..)
, TemporaryDownloadUrl (..)
) where

import IHP.Prelude
import qualified Network.Minio as Minio
import qualified Network.Wai.Parse as Wai

data FileStorage
    = StaticDirStorage -- ^ Stores files publicly visible inside the project's @static@ directory
    | S3Storage { FileStorage -> ConnectInfo
connectInfo :: Minio.ConnectInfo, FileStorage -> Text
bucket :: Text, FileStorage -> Text
baseUrl :: Text } -- ^ Stores files inside a S3 compatible cloud storage

-- | Result of a 'storeFile' operation
data StoredFile = StoredFile { StoredFile -> Text
path :: Text, StoredFile -> Text
url :: Text }

-- | Options that can be passed to 'storeFileWithOptions'
data StoreFileOptions = StoreFileOptions
    { StoreFileOptions -> Text
directory :: Text -- ^ Directory on S3 or inside the @static@ where all files are placed
    , StoreFileOptions -> FileInfo LByteString -> IO (Maybe Text)
contentDisposition :: Wai.FileInfo LByteString -> IO (Maybe Text) -- ^ The browser uses the content disposition header to detect if the file should be shown inside the browser or should be downloaded as a file attachment. You can provide a function here that returns a custom content-disposition header based on the uploaded file. This currently only works with the S3 storage. See 'contentDispositionAttachmentAndFileName' for standard configuration.
    , StoreFileOptions
-> FileInfo LByteString -> IO (FileInfo LByteString)
preprocess :: Wai.FileInfo LByteString -> IO (Wai.FileInfo LByteString) -- ^ Can be used to preprocess the file before storing it inside the storage. See 'applyImageMagick' for preprocessing images.
    , StoreFileOptions -> Maybe UUID
fileName :: Maybe UUID -- ^ Optional filename. We use UUID for security reasons.
    }

instance Default StoreFileOptions where
    def :: StoreFileOptions
def = StoreFileOptions
        { $sel:directory:StoreFileOptions :: Text
directory = Text
""
        , $sel:contentDisposition:StoreFileOptions :: FileInfo LByteString -> IO (Maybe Text)
contentDisposition = IO (Maybe Text) -> FileInfo LByteString -> IO (Maybe Text)
forall a b. a -> b -> a
const (Maybe Text -> IO (Maybe Text)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Text
forall a. Maybe a
Nothing)
        , $sel:preprocess:StoreFileOptions :: FileInfo LByteString -> IO (FileInfo LByteString)
preprocess = FileInfo LByteString -> IO (FileInfo LByteString)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
        , $sel:fileName:StoreFileOptions :: Maybe UUID
fileName = Maybe UUID
forall a. Maybe a
Nothing
        }

-- | A signed url to a file. See 'createTemporaryDownloadUrl'
data TemporaryDownloadUrl = TemporaryDownloadUrl { TemporaryDownloadUrl -> Text
url :: Text, TemporaryDownloadUrl -> UTCTime
expiredAt :: UTCTime }