module Args
  ( CommonOptions (..),
    SubmitOptions (..),
    CheckOptions (..),
    ListOptions (..),
    Mode (..),
    runArgsParser,
  )
where

import Distribution.ArchHs.Options
import Distribution.ArchHs.Utils (archHsVersion)

-----------------------------------------------------------------------------

data CommonOptions = CommonOptions
  { optHackage :: HackageDBOptions,
    optExtraDB :: ExtraDBOptions
  }

commonOptionsParser :: Parser CommonOptions
commonOptionsParser =
  CommonOptions <$> hackageDBOptionsParser <*> extraDBOptionsParser

-----------------------------------------------------------------------------

data SubmitOptions = SubmitOptions
  { optOutput :: FilePath,
    optUpload :: Bool
  }

submitOptionsParser :: Parser SubmitOptions
submitOptionsParser =
  SubmitOptions
    <$> option
      str
      ( long "output"
          <> metavar "PATH"
          <> short 'o'
          <> help "Output path of generated .csv file"
          <> value ""
      )
    <*> switch
      ( long "upload"
          <> short 'u'
          <> help "Upload to hackage"
      )

-----------------------------------------------------------------------------

data CheckOptions = CheckOptions
  { optShowGHCLibs :: Bool,
    optDepCheck :: Bool,
    optVerbose :: Bool
  }

checkOptionsParser :: Parser CheckOptions
checkOptionsParser =
  CheckOptions
    <$> switch (long "show-ghc-libs" <> help "Include GHC and GHC libs")
    <*> switch (long "depcheck" <> help "Check whether newer Hackage versions are currently upgradable")
    <*> switch (long "verbose" <> help "Show dependency and reverse dependency ranges that block --depcheck candidates")

-----------------------------------------------------------------------------

newtype ListOptions = ListOptions
  { optWithVersion :: Bool
  }

listOptionsParser :: Parser ListOptions
listOptionsParser =
  ListOptions
    <$> switch (short 'v' <> long "with-version" <> help "Show package version")

-----------------------------------------------------------------------------

data Mode
  = Submit CommonOptions SubmitOptions
  | Check CommonOptions CheckOptions
  | List ExtraDBOptions ListOptions

runArgsParser :: IO Mode
runArgsParser =
  snd <$> do
    simpleOptions
      archHsVersion
      "arch-hs-sync - sync metadata of Haskell packages between [extra] and Hackage"
      "arch-hs-sync is designed to be used by Hackage distribution maintainers"
      (pure ())
      $ do
        addCommand
          "submit"
          "submit distribution information to Hackage"
          id
          (Submit <$> commonOptionsParser <*> submitOptionsParser)
        addCommand
          "check"
          "check newer Hackage versions for Haskell packages in [extra]"
          id
          (Check <$> commonOptionsParser <*> checkOptionsParser)
        addCommand
          "list"
          "list all Haskell packages in [extra]"
          id
          (List <$> extraDBOptionsParser <*> listOptionsParser)
