<commit_before>{-# LANGUAGE GADTs             #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards   #-}

-- Module      : Khan.Internal.Options
-- Copyright   : (c) 2013 <NAME> <<EMAIL>>
-- License     : This Source Code Form is subject to the terms of
--               the Mozilla Public License, v. 2.0.
--               A copy of the MPL can be found in the LICENSE file or
--               you can obtain it at http://mozilla.org/MPL/2.0/.
-- Maintainer  : <NAME> <<EMAIL>>
-- Stability   : experimental
-- Portability : non-portable (GHC extensions)

module Khan.Internal.Options
    (
    -- * GADT/Class
      Options     (..)
    , Command     (..)

    -- * Common
    , Common      (..)
    , RKeysBucket (..)
    , LKeysDir    (..)
    , CacheDir    (..)
    , ConfigDir   (..)
    , commonParser

    -- * Top-level
    , group
    , command

    -- * Overrides
    , readOption
    , switchOption
    , textOption
    , pathOption
    , stringOption
    , integralOption
    , customOption
    , argsOption

    -- * Common
    , roleOption
    , envOption
    , versionOption
    , keyOption
    , trustOption
    , policyOption
    , ansibleOption
    , userOption

    -- * Validation
    , check
    , checkIO
    , checkPath

    , module Export
    ) where

import qualified Data.Attoparsec.Text      as AText
import qualified Data.HashMap.Strict       as Map
import           Data.SemVer
import           Data.String
import qualified Data.Text                 as Text
import qualified Filesystem.Path.CurrentOS as Path
import           Khan.Internal.IO
import           Khan.Internal.Types
import           Khan.Prelude
import           Network.AWS
import           Options.Applicative       as Export hiding (command, info, execParser)
import qualified Options.Applicative       as Options
import           Prelude                   (error)
import qualified Shelly                    as Shell

data Command where
    Command :: Options a => (Common -> a -> AWS ()) -> a -> Command

class Options a where
    discover :: Bool -> Common -> a -> AWS a
    validate :: MonadIO m => a -> EitherT AWSError m ()

    discover _ _ = return
    validate     = void . return

data Common = Common
    { cDebug  :: !Bool
    , cSilent :: !Bool
    , cRegion :: !Region
    , cRKeys  :: Maybe RKeysBucket
    , cLKeys  :: !LKeysDir
    , cCache  :: !CacheDir
    , cConfig :: !ConfigDir
    } deriving (Show)

newtype RKeysBucket = RKeysBucket { rKeysBucket :: Text }
    deriving (Eq, Show)

newtype LKeysDir = LKeysDir { lKeysPath :: FilePath }
    deriving (Eq, Show)

newtype CacheDir = CacheDir { cacheDir :: FilePath }
    deriving (Eq, Show)

newtype ConfigDir = ConfigDir { configDir :: FilePath }
    deriving (Eq, Show)

commonParser :: EnvMap -> Parser Common
commonParser env = Common
    <$> switchOption "debug" False
        "Log debug output."
    <*> switchOption "silent" False
        "Suppress standard log output."
    <*> readOption "region" "REGION"
         ( evalue (readMay . Text.unpack) "KHAN_REGION" env
        <> short 'R'
         ) "Region to operate in."
    <*> optional (RKeysBucket <$> textOption "remote-keys"
        ( etext "KHAN_RKEYS" env
        <> short 'K'
        ) "Bucket to retrieve/store certificates.")
    <*> (LKeysDir <$> pathOption "local-keys"
         ( value "/etc/ssl/khan"
        <> epath "KHAN_LKEYS" env
        <> short 'L'
         ) "Path to certificates.")
    <*> (CacheDir <$> pathOption "cache"
         ( value "/var/cache/khan"
        <> epath "KHAN_CACHE" env
         ) "Path to cache.")
    <*> (ConfigDir <$> pathOption "config"
         ( value "/etc/khan"
        <> epath "KHAN_CONFIG" env
        <> short 'C'
         ) "Path to configuration files.")

instance Options Common where
    validate Common{..} = do
       check cRegion " --region or KHAN_REGION must be specified."

       checkPath (lKeysPath cLKeys)  " specified by --local-keys or KHAN_LKEYS must exist."
       checkPath (cacheDir cCache)   " specified by --cache or KHAN_CACHE must exist."
       checkPath (configDir cConfig) " specified by --config or KHAN_CONFIG must exist."<commit_msg>Consistent naming<commit_after>{-# LANGUAGE GADTs             #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards   #-}

-- Module      : Khan.Internal.Options
-- Copyright   : (c) 2013 <NAME> <<EMAIL>>
-- License     : This Source Code Form is subject to the terms of
--               the Mozilla Public License, v. 2.0.
--               A copy of the MPL can be found in the LICENSE file or
--               you can obtain it at http://mozilla.org/MPL/2.0/.
-- Maintainer  : <NAME> <<EMAIL>>
-- Stability   : experimental
-- Portability : non-portable (GHC extensions)

module Khan.Internal.Options
    (
    -- * GADT/Class
      Options     (..)
    , Command     (..)

    -- * Common
    , Common      (..)
    , RKeysBucket (..)
    , LKeysDir    (..)
    , CacheDir    (..)
    , ConfigDir   (..)
    , commonParser

    -- * Top-level
    , group
    , command

    -- * Overrides
    , readOption
    , switchOption
    , textOption
    , pathOption
    , stringOption
    , integralOption
    , customOption
    , argsOption

    -- * Common
    , roleOption
    , envOption
    , versionOption
    , keyOption
    , trustOption
    , policyOption
    , ansibleOption
    , userOption

    -- * Validation
    , check
    , checkIO
    , checkPath

    , module Export
    ) where

import qualified Data.Attoparsec.Text      as AText
import qualified Data.HashMap.Strict       as Map
import           Data.SemVer
import           Data.String
import qualified Data.Text                 as Text
import qualified Filesystem.Path.CurrentOS as Path
import           Khan.Internal.IO
import           Khan.Internal.Types
import           Khan.Prelude
import           Network.AWS
import           Options.Applicative       as Export hiding (command, info, execParser)
import qualified Options.Applicative       as Options
import           Prelude                   (error)
import qualified Shelly                    as Shell

data Command where
    Command :: Options a => (Common -> a -> AWS ()) -> a -> Command

class Options a where
    discover :: Bool -> Common -> a -> AWS a
    validate :: MonadIO m => a -> EitherT AWSError m ()

    discover _ _ = return
    validate     = void . return

data Common = Common
    { cDebug  :: !Bool
    , cSilent :: !Bool
    , cRegion :: !Region
    , cRKeys  :: Maybe RKeysBucket
    , cLKeys  :: !LKeysDir
    , cCache  :: !CacheDir
    , cConfig :: !ConfigDir
    } deriving (Show)

newtype RKeysBucket = RKeysBucket { rKeysBucket :: Text }
    deriving (Eq, Show)

newtype LKeysDir = LKeysDir { lKeysDir :: FilePath }
    deriving (Eq, Show)

newtype CacheDir = CacheDir { cacheDir :: FilePath }
    deriving (Eq, Show)

newtype ConfigDir = ConfigDir { configDir :: FilePath }
    deriving (Eq, Show)

commonParser :: EnvMap -> Parser Common
commonParser env = Common
    <$> switchOption "debug" False
        "Log debug output."
    <*> switchOption "silent" False
        "Suppress standard log output."
    <*> readOption "region" "REGION"
         ( evalue (readMay . Text.unpack) "KHAN_REGION" env
        <> short 'R'
         ) "Region to operate in."
    <*> optional (RKeysBucket <$> textOption "remote-keys"
        ( etext "KHAN_RKEYS" env
        <> short 'K'
        ) "Bucket to retrieve/store certificates.")
    <*> (LKeysDir <$> pathOption "local-keys"
         ( value "/etc/ssl/khan"
        <> epath "KHAN_LKEYS" env
        <> short 'L'
         ) "Path to certificates.")
    <*> (CacheDir <$> pathOption "cache"
         ( value "/var/cache/khan"
        <> epath "KHAN_CACHE" env
         ) "Path to cache.")
    <*> (ConfigDir <$> pathOption "config"
         ( value "/etc/khan"
        <> epath "KHAN_CONFIG" env
        <> short 'C'
         ) "Path to configuration files.")

instance Options Common where
    validate Common{..} = do
       check cRegion " --region or KHAN_REGION must be specified."

       checkPath (lKeysDir cLKeys)  " specified by --local-keys or KHAN_LKEYS must exist."
       checkPath (cacheDir cCache)   " specified by --cache or KHAN_CACHE must exist."
       checkPath (configDir cConfig) " specified by --config or KHAN_CONFIG must exist."
{'fraction_non_alphanumeric': 0.11018562589243218, 'fraction_numerical': 0.0019038553069966682, 'mean_word_length': 2.0408827785817656, 'pattern_counts': {'":': 0, '<': 51, '<?xml version=': 0, '>': 73, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3923681', 'n_tokens_mistral': 2582, 'n_tokens_neox': 2520, 'n_words': 738}