module Bricoleur.Opts
  ( Command (..),
    Options (..),
    getOpts,
  )
where

import Control.Applicative ((<|>))
import qualified Options.Applicative as Opt
import qualified System.Directory as Sys
import qualified System.FilePath as Sys

data Command
  = Test
  | Splice
  deriving (Eq, Show)

data Options = Options
  { optFile :: FilePath,
    optVerbose :: Bool,
    optCommand :: Command
  }
  deriving (Eq, Show)

desc :: String
desc = "Bricoleur: a tool for testing and stiching code into documents"

opts :: Opt.ParserInfo Options
opts =
  Opt.info
    (p Opt.<**> Opt.helper)
    ( Opt.progDesc desc
        <> Opt.fullDesc
        <> Opt.header "arglbargl"
    )
  where
    p =
      Options <$> (path <|> pure "")
        <*> verbose
        <*> Opt.subparser (test <> splice)

    path =
      Opt.strOption
        ( Opt.short 'f'
            <> Opt.long "file"
            <> Opt.metavar "PATH"
            <> Opt.help "The path to the project file"
        )

    verbose =
      Opt.switch
        ( Opt.short 'v'
            <> Opt.long "verbose"
            <> Opt.help "Show debug messages"
        )

    test =
      Opt.command "test" $
        Opt.info
          (pure Test Opt.<**> Opt.helper)
          (Opt.progDesc "test the provided sources")

    splice =
      Opt.command "splice" $
        Opt.info
          (pure Splice Opt.<**> Opt.helper)
          (Opt.progDesc "splice sources into a final draft")

getOpts :: IO Options
getOpts = do
  cwd <- Sys.getCurrentDirectory
  options <- Opt.execParser opts
  return $
    if null (optFile options)
      then options {optFile = cwd Sys.</> "bricoleur"}
      else options
