content: {-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
  
  {-# HLINT ignore "Use maybe" #-}
  module AirGQL.ExternalAppContext (
    SandboxingConfig (..),
    ExternalAppContext (..),
    getExternalAppContext,
  ) where
  
  import Protolude (
    FilePath,
    IO,
    Maybe (Just, Nothing),
    Show,
    Text,
    not,
    pure,
    ($),
    (&&),
    (/=),
    (<|>),
    (==),
   )
  import Protolude qualified as P
  
  import Data.ByteString qualified as BS
  import Data.Text qualified as T
  import System.Environment (lookupEnv)
  import System.Info (os)
  import System.Process.Typed (ExitCode (ExitSuccess), proc, readProcessStdout)
  
  
  lookupBinaryPath :: Text -> IO (Maybe FilePath)
  lookupBinaryPath name = do
    (code, resultBS) <- readProcessStdout $ proc "which" [T.unpack name]
    let result = T.strip $ P.decodeUtf8 $ BS.toStrict resultBS
    pure $
      if code == ExitSuccess
        && result /= ""
        && not ("which: no" `T.isInfixOf` result)
        then Just $ T.unpack result
        else Nothing
  
  
  data SandboxingConfig = SandboxingConfig
    { firejail :: FilePath
    , extraBinds :: [FilePath]
    }
    deriving (Show)
  
  
  data ExternalAppContext = ExternalAppContext
    { sqlite :: FilePath
    , sqliteLib :: Maybe FilePath
    , baseUrl :: Text
    }
    deriving (Show)
  
  
  getExternalAppContext :: Text -> IO ExternalAppContext
  getExternalAppContext baseUrl = do
    sqlite <- lookupBinaryPath "sqlite3"
    sqliteEnv <- lookupEnv "AIRGQL_SQLITE_BIN"
    sqliteLib <- lookupEnv "AIRGQL_SQLITE_LIB"
  
    pure $
      ExternalAppContext
        { baseUrl = baseUrl
        , sqlite = P.fromMaybe "/usr/bin/sqlite3" $ sqliteEnv <|> sqlite
        , sqliteLib =
            sqliteLib
              <|> if os == "darwin"
                then Just "/usr/local/opt/sqlite/lib/libsqlite3.dylib"
                else Nothing
        }
  