{-# LANGUAGE OverloadedStrings #-}
module CommandLine where
import Options.Applicative
-- Define data types for our commands and options
data Command
= ExtIP ExtIPOptions
| Version VersionOptions
| Kernel KernelOptions
| Sleep SleepOptions
| ZfsCheck ZfsCheckOptions
| WireGuard WireGuardOptions
| NetMan NetManOptions
| SysNet SysNetOptions
deriving Show
data ExtIPOptions = ExtIPOptions
{ nolocation :: Bool
, ipv6 :: Bool
} deriving Show
data KernelOptions = KernelOptions
{ justVersion :: Bool } deriving Show
data SleepOptions = SleepOptions
{ secondsToSleep :: Maybe Int } deriving Show
data VersionOptions = VersionOptions Bool deriving Show
data ZfsCheckOptions = ZfsCheckOptions
{ full :: Bool } deriving Show
data WireGuardOptions = WireGuardOptions
{ listWGs :: Bool
, activateWG :: Maybe String
, enableWG :: Maybe String
, deactivateWG :: Bool
, disableWG :: Bool
, reactivateWG :: Bool
} deriving Show
data NetManOptions = NetManOptions
{ activateNM :: Bool
, enableNM :: Bool
, deactivateNM :: Bool
, disableNM :: Bool
, reactivateNM :: Bool
} deriving Show
data SysNetOptions = SysNetOptions
{ activateSN :: Bool
, enableSN :: Bool
, deactivateSN :: Bool
, disableSN :: Bool
, reactivateSN :: Bool
} deriving Show
data GlobalOptions = GlobalOptions
{ verbose :: Bool } deriving Show
globalOptionsParser :: Parser GlobalOptions
globalOptionsParser = GlobalOptions
<$> switch ( long "verbose"
<> short 'v'
<> help "Enable verbose mode" )
extipOptionsParser :: Parser ExtIPOptions
extipOptionsParser = ExtIPOptions
<$> switch ( long "nolocation"
<> short 'n'
<> help "Don't display location information" )
<*> switch ( long "ipv6"
<> short 'i'
<> help "Display the IPv6 address" )
kernelOptionsParser :: Parser KernelOptions
kernelOptionsParser = KernelOptions
<$> switch ( long "justversion"
<> short 'j'
<> help "Just display the numerical version number, no adjoining text." )
-- version has no options
versionOptionsParser :: Parser VersionOptions
versionOptionsParser = VersionOptions
<$> switch ( long "noop" )
sleepOptionsParser :: Parser SleepOptions
sleepOptionsParser = SleepOptions
<$> optional (option auto ( long "wait"
<> short 'w'
<> metavar "SECONDS"
<> help "Seconds to wait before going to sleep"))
zfscheckOptionsParser :: Parser ZfsCheckOptions
zfscheckOptionsParser = ZfsCheckOptions
<$> switch
( long "full"
<> short 'f'
<> help "Check all kernel versions" )
wgOptionsParser :: Parser WireGuardOptions
wgOptionsParser = WireGuardOptions
<$> switch ( long "list"
<> short 'l'
<> help "List all installed WireGuardG VPNs")
<*> optional (strOption ( long "activate"
<> short 'a'
<> metavar "WGVPN"
<> help "WireGuard VPN to activate"))
<*> optional (strOption ( long "enable"
<> short 'A'
<> metavar "WGVPN"
<> help "WireGuard VPN to enable and activate"))
<*> switch ( long "deactivate"
<> short 'd'
<> help "Deactivate (but not disable) all WireGuard VPNs")
<*> switch ( long "disable"
<> short 'D'
<> help "Disable (but not deactivate) all WireGuard VPNs")
<*> switch ( long "reactivate"
<> short 'r'
<> help "Reactivate currently active WireGuardG VPNs")
nmOptionsParser :: Parser NetManOptions
nmOptionsParser = NetManOptions
<$> switch ( long "activate"
<> short 'a'
<> help "Activate (start) NetworkManager")
<*> switch ( long "enable"
<> short 'A'
<> help "Enable and Activate (start) NetworkManager")
<*> switch ( long "deactivate"
<> short 'd'
<> help "Deactivate (stop) NetworkManager")
<*> switch ( long "disable"
<> short 'D'
<> help "Disable and Deactivate (stop) NetworkManager")
<*> switch ( long "reactivate"
<> short 'r'
<> help "Reactivate (restart) NetworkManager")
snOptionsParser :: Parser SysNetOptions
snOptionsParser = SysNetOptions
<$> switch ( long "activate"
<> short 'a'
<> help "Activate (start) systemd-networkd socket and service")
<*> switch ( long "enable"
<> short 'A'
<> help "Enable and Activate (start) systemd-networkd socket and service")
<*> switch ( long "deactivate"
<> short 'd'
<> help "Deactivate (stop) systemd-networkd socket and service")
<*> switch ( long "disable"
<> short 'D'
<> help "Disable and Deactivate (stop) systemd-networkd socket and service")
<*> switch ( long "reactivate"
<> short 'r'
<> help "Reactivate (restart) systemd-networkd socket and service")
-- Combine the subcommand parsers
commandParser :: Parser Command
commandParser = subparser
( command "extip" (info (ExtIP <$> extipOptionsParser) (progDesc "Display external IP address"))
<> command "kernel" (info (Kernel <$> kernelOptionsParser) (progDesc "Display kernel information, both installed and currently running"))
<> command "sleep" (info (Sleep <$> sleepOptionsParser) (progDesc "Put the machine to sleep"))
<> command "version" (info (Version <$> versionOptionsParser) (progDesc "Version of Swiss Army Knife"))
<> command "zfscheck" (info (ZfsCheck <$> zfscheckOptionsParser) (progDesc "Check zfs availibility for the current kernel"))
<> command "wg" (info (WireGuard <$> wgOptionsParser) (progDesc "Manage WireGuard VPNs"))
<> command "nm" (info (NetMan <$> nmOptionsParser) (progDesc "Manage NetworkManager"))
<> command "sn" (info (SysNet <$> snOptionsParser) (progDesc "Manage systemd-networkd"))
)
-- Combine global options with the command parser
opts :: Parser (GlobalOptions, Command)
opts = (,) <$> globalOptionsParser <*> commandParser