-- Options.hs: hOpenPGP key tool command-line options
-- Copyright © 2013-2026  Clint Adams
--
-- vim: softtabstop=4:shiftwidth=4:expandtab
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Affero General Public License as
-- published by the Free Software Foundation, either version 3 of the
-- License, or (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU Affero General Public License for more details.
--
-- You should have received a copy of the GNU Affero General Public License
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.

module HOpenPGP.Tools.Hokey.Options
  (
  -- CanonicalizeOptions
    FetchOptions(..)
  , InjectSSHAgentOptions(..)
  , LintOptions(..)
  , fetchO
  , injectSSHAgentO
  , lintO
  , FetchMethod(..)
  , LintOutputFormat(..)
  ) where

import Codec.Encryption.OpenPGP.Serialize ()
import Control.Applicative (optional)
import HOpenPGP.Tools.Common.HKP (FetchValidationMethod(..))

import Options.Applicative.Builder
  ( argument
  , auto
  , help
  , helpDoc
  , long
  , metavar
  , option
  , showDefault
  , str
  , value
  )
import Options.Applicative.Types (Parser)
import Prettyprinter
  ( hardline
  , list
  , pretty
  )

data LintOutputFormat
  = Pretty
  | JSON
  | YAML
  deriving (Bounded, Enum, Eq, Read, Show)

data LintOptions =
  LintOptions
    { lintOutputFormat :: LintOutputFormat
    }

data FetchOptions =
  FetchOptions
    { keyServer :: String
    , fetchMethod :: FetchMethod
    , fetchValidation :: FetchValidationMethod
    , fetchQuery :: String
    }

data InjectSSHAgentOptions =
  InjectSSHAgentOptions
    { injectSSHAgentFromFD :: Maybe Int
    , injectSSHAgentSocket :: Maybe String
    , injectSSHAgentComment :: Maybe String
    }

data FetchMethod
  = HKP
  | WKD
  deriving (Bounded, Enum, Eq, Read, Show)

lintO :: Parser LintOptions
lintO =
  LintOptions <$>
  option
    auto
    (long "output-format" <> metavar "FORMAT" <> value Pretty <> showDefault <>
     ofHelp)
  where
    ofHelp =
      helpDoc . Just $ pretty "output format" <> hardline <>
      list (map (pretty . show) ofchoices)
    ofchoices = [minBound .. maxBound] :: [LintOutputFormat]

fetchO :: Parser FetchOptions
fetchO =
  FetchOptions <$>
  option
    str
    (long "keyserver" <> metavar "URL" <>
     value "http://pool.sks-keyservers.net:11371" <>
     showDefault <>
     help "HKP server (used only when --method=HKP)") <*>
  option
    auto
    (long "method" <> metavar "METHOD" <> value HKP <> showDefault <> fmHelp) <*>
  option
    auto
    (long "validation-method" <> metavar "METHOD" <>
     value MatchPrimaryKeyFingerprint <>
     showDefault <>
     vmHelp) <*>
  argument str (metavar "QUERY")
  where
    fmHelp =
     helpDoc . Just $ pretty "fetch method" <> hardline <>
     list (map (pretty . show) fmchoices)
    fmchoices = [minBound .. maxBound] :: [FetchMethod]
    vmHelp =
     helpDoc . Just $ pretty "validation method" <> hardline <>
     list (map (pretty . show) vmchoices)
    vmchoices = [minBound .. maxBound] :: [FetchValidationMethod]

injectSSHAgentO :: Parser InjectSSHAgentOptions
injectSSHAgentO =
  InjectSSHAgentOptions <$>
  optional
    (option
       auto
       (long "from-fd" <>
        metavar "FD" <>
        help "read binary gpg --export-secret-keys bytes from this already-open file descriptor")) <*>
  optional
    (option
       str
       (long "ssh-agent-socket" <>
        metavar "PATH" <> help "path to ssh-agent socket (defaults to SSH_AUTH_SOCK)")) <*>
  optional
    (option
       str
       (long "comment" <>
        metavar "TEXT" <> help "comment string stored with the injected SSH identity"))
