-- 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 Options.Applicative.Builder
    ( argument
    , auto
    , help
    , helpDoc
    , long
    , metavar
    , option
    , showDefault
    , str
    , value
    )
import Options.Applicative.Types (Parser)
import Prettyprinter
    ( hardline
    , list
    , pretty
    )

import HOpenPGP.Tools.Common.HKP (FetchValidationMethod (..))

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"
                )
            )
