module IpeDb.Options (
  Options (..),
  Command (..),
  IndexOptions (..),
  QueryOptions (..),
  parseOptions,
  options,
  commands,
  queryCommand,
  indexCommand,
) where

import IpeDb.InfoProv (IpeId (..))
import Options.Applicative

data Options = Options
  { Options -> FilePath
databaseFp :: FilePath
  , Options -> Command
command :: Command
  }
  deriving (Int -> Options -> ShowS
[Options] -> ShowS
Options -> FilePath
(Int -> Options -> ShowS)
-> (Options -> FilePath) -> ([Options] -> ShowS) -> Show Options
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Options -> ShowS
showsPrec :: Int -> Options -> ShowS
$cshow :: Options -> FilePath
show :: Options -> FilePath
$cshowList :: [Options] -> ShowS
showList :: [Options] -> ShowS
Show, Options -> Options -> Bool
(Options -> Options -> Bool)
-> (Options -> Options -> Bool) -> Eq Options
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Options -> Options -> Bool
== :: Options -> Options -> Bool
$c/= :: Options -> Options -> Bool
/= :: Options -> Options -> Bool
Eq, Eq Options
Eq Options =>
(Options -> Options -> Ordering)
-> (Options -> Options -> Bool)
-> (Options -> Options -> Bool)
-> (Options -> Options -> Bool)
-> (Options -> Options -> Bool)
-> (Options -> Options -> Options)
-> (Options -> Options -> Options)
-> Ord Options
Options -> Options -> Bool
Options -> Options -> Ordering
Options -> Options -> Options
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Options -> Options -> Ordering
compare :: Options -> Options -> Ordering
$c< :: Options -> Options -> Bool
< :: Options -> Options -> Bool
$c<= :: Options -> Options -> Bool
<= :: Options -> Options -> Bool
$c> :: Options -> Options -> Bool
> :: Options -> Options -> Bool
$c>= :: Options -> Options -> Bool
>= :: Options -> Options -> Bool
$cmax :: Options -> Options -> Options
max :: Options -> Options -> Options
$cmin :: Options -> Options -> Options
min :: Options -> Options -> Options
Ord)

data Command
  = Index IndexOptions
  | Query QueryOptions
  deriving (Int -> Command -> ShowS
[Command] -> ShowS
Command -> FilePath
(Int -> Command -> ShowS)
-> (Command -> FilePath) -> ([Command] -> ShowS) -> Show Command
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Command -> ShowS
showsPrec :: Int -> Command -> ShowS
$cshow :: Command -> FilePath
show :: Command -> FilePath
$cshowList :: [Command] -> ShowS
showList :: [Command] -> ShowS
Show, Command -> Command -> Bool
(Command -> Command -> Bool)
-> (Command -> Command -> Bool) -> Eq Command
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Command -> Command -> Bool
== :: Command -> Command -> Bool
$c/= :: Command -> Command -> Bool
/= :: Command -> Command -> Bool
Eq, Eq Command
Eq Command =>
(Command -> Command -> Ordering)
-> (Command -> Command -> Bool)
-> (Command -> Command -> Bool)
-> (Command -> Command -> Bool)
-> (Command -> Command -> Bool)
-> (Command -> Command -> Command)
-> (Command -> Command -> Command)
-> Ord Command
Command -> Command -> Bool
Command -> Command -> Ordering
Command -> Command -> Command
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Command -> Command -> Ordering
compare :: Command -> Command -> Ordering
$c< :: Command -> Command -> Bool
< :: Command -> Command -> Bool
$c<= :: Command -> Command -> Bool
<= :: Command -> Command -> Bool
$c> :: Command -> Command -> Bool
> :: Command -> Command -> Bool
$c>= :: Command -> Command -> Bool
>= :: Command -> Command -> Bool
$cmax :: Command -> Command -> Command
max :: Command -> Command -> Command
$cmin :: Command -> Command -> Command
min :: Command -> Command -> Command
Ord)

data IndexOptions = IndexOptions
  { IndexOptions -> FilePath
eventlog :: FilePath
  }
  deriving (Int -> IndexOptions -> ShowS
[IndexOptions] -> ShowS
IndexOptions -> FilePath
(Int -> IndexOptions -> ShowS)
-> (IndexOptions -> FilePath)
-> ([IndexOptions] -> ShowS)
-> Show IndexOptions
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> IndexOptions -> ShowS
showsPrec :: Int -> IndexOptions -> ShowS
$cshow :: IndexOptions -> FilePath
show :: IndexOptions -> FilePath
$cshowList :: [IndexOptions] -> ShowS
showList :: [IndexOptions] -> ShowS
Show, IndexOptions -> IndexOptions -> Bool
(IndexOptions -> IndexOptions -> Bool)
-> (IndexOptions -> IndexOptions -> Bool) -> Eq IndexOptions
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: IndexOptions -> IndexOptions -> Bool
== :: IndexOptions -> IndexOptions -> Bool
$c/= :: IndexOptions -> IndexOptions -> Bool
/= :: IndexOptions -> IndexOptions -> Bool
Eq, Eq IndexOptions
Eq IndexOptions =>
(IndexOptions -> IndexOptions -> Ordering)
-> (IndexOptions -> IndexOptions -> Bool)
-> (IndexOptions -> IndexOptions -> Bool)
-> (IndexOptions -> IndexOptions -> Bool)
-> (IndexOptions -> IndexOptions -> Bool)
-> (IndexOptions -> IndexOptions -> IndexOptions)
-> (IndexOptions -> IndexOptions -> IndexOptions)
-> Ord IndexOptions
IndexOptions -> IndexOptions -> Bool
IndexOptions -> IndexOptions -> Ordering
IndexOptions -> IndexOptions -> IndexOptions
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: IndexOptions -> IndexOptions -> Ordering
compare :: IndexOptions -> IndexOptions -> Ordering
$c< :: IndexOptions -> IndexOptions -> Bool
< :: IndexOptions -> IndexOptions -> Bool
$c<= :: IndexOptions -> IndexOptions -> Bool
<= :: IndexOptions -> IndexOptions -> Bool
$c> :: IndexOptions -> IndexOptions -> Bool
> :: IndexOptions -> IndexOptions -> Bool
$c>= :: IndexOptions -> IndexOptions -> Bool
>= :: IndexOptions -> IndexOptions -> Bool
$cmax :: IndexOptions -> IndexOptions -> IndexOptions
max :: IndexOptions -> IndexOptions -> IndexOptions
$cmin :: IndexOptions -> IndexOptions -> IndexOptions
min :: IndexOptions -> IndexOptions -> IndexOptions
Ord)

data QueryOptions = QueryOptions
  { QueryOptions -> IpeId
ipeId :: IpeId
  }
  deriving (Int -> QueryOptions -> ShowS
[QueryOptions] -> ShowS
QueryOptions -> FilePath
(Int -> QueryOptions -> ShowS)
-> (QueryOptions -> FilePath)
-> ([QueryOptions] -> ShowS)
-> Show QueryOptions
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> QueryOptions -> ShowS
showsPrec :: Int -> QueryOptions -> ShowS
$cshow :: QueryOptions -> FilePath
show :: QueryOptions -> FilePath
$cshowList :: [QueryOptions] -> ShowS
showList :: [QueryOptions] -> ShowS
Show, QueryOptions -> QueryOptions -> Bool
(QueryOptions -> QueryOptions -> Bool)
-> (QueryOptions -> QueryOptions -> Bool) -> Eq QueryOptions
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: QueryOptions -> QueryOptions -> Bool
== :: QueryOptions -> QueryOptions -> Bool
$c/= :: QueryOptions -> QueryOptions -> Bool
/= :: QueryOptions -> QueryOptions -> Bool
Eq, Eq QueryOptions
Eq QueryOptions =>
(QueryOptions -> QueryOptions -> Ordering)
-> (QueryOptions -> QueryOptions -> Bool)
-> (QueryOptions -> QueryOptions -> Bool)
-> (QueryOptions -> QueryOptions -> Bool)
-> (QueryOptions -> QueryOptions -> Bool)
-> (QueryOptions -> QueryOptions -> QueryOptions)
-> (QueryOptions -> QueryOptions -> QueryOptions)
-> Ord QueryOptions
QueryOptions -> QueryOptions -> Bool
QueryOptions -> QueryOptions -> Ordering
QueryOptions -> QueryOptions -> QueryOptions
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: QueryOptions -> QueryOptions -> Ordering
compare :: QueryOptions -> QueryOptions -> Ordering
$c< :: QueryOptions -> QueryOptions -> Bool
< :: QueryOptions -> QueryOptions -> Bool
$c<= :: QueryOptions -> QueryOptions -> Bool
<= :: QueryOptions -> QueryOptions -> Bool
$c> :: QueryOptions -> QueryOptions -> Bool
> :: QueryOptions -> QueryOptions -> Bool
$c>= :: QueryOptions -> QueryOptions -> Bool
>= :: QueryOptions -> QueryOptions -> Bool
$cmax :: QueryOptions -> QueryOptions -> QueryOptions
max :: QueryOptions -> QueryOptions -> QueryOptions
$cmin :: QueryOptions -> QueryOptions -> QueryOptions
min :: QueryOptions -> QueryOptions -> QueryOptions
Ord)

parseOptions :: IO Options
parseOptions :: IO Options
parseOptions = ParserInfo Options -> IO Options
forall a. ParserInfo a -> IO a
execParser ParserInfo Options
opts
 where
  opts :: ParserInfo Options
opts =
    Parser Options -> InfoMod Options -> ParserInfo Options
forall a. Parser a -> InfoMod a -> ParserInfo a
info
      (Parser Options
options Parser Options -> Parser (Options -> Options) -> Parser Options
forall (f :: * -> *) a b. Applicative f => f a -> f (a -> b) -> f b
<**> Parser (Options -> Options)
forall a. Parser (a -> a)
helper)
      ( InfoMod Options
forall a. InfoMod a
fullDesc
          InfoMod Options -> InfoMod Options -> InfoMod Options
forall a. Semigroup a => a -> a -> a
<> FilePath -> InfoMod Options
forall a. FilePath -> InfoMod a
progDesc FilePath
"Index for Info Provenance entries"
          InfoMod Options -> InfoMod Options -> InfoMod Options
forall a. Semigroup a => a -> a -> a
<> FilePath -> InfoMod Options
forall a. FilePath -> InfoMod a
header FilePath
"ipedb - A database for info provenance entries"
      )

options :: Parser Options
options :: Parser Options
options =
  FilePath -> Command -> Options
Options
    (FilePath -> Command -> Options)
-> Parser FilePath -> Parser (Command -> Options)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Mod ArgumentFields FilePath -> Parser FilePath
forall s. IsString s => Mod ArgumentFields s -> Parser s
strArgument
      ( FilePath -> Mod ArgumentFields FilePath
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"FILENAME"
          Mod ArgumentFields FilePath
-> Mod ArgumentFields FilePath -> Mod ArgumentFields FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod ArgumentFields FilePath
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Database location"
      )
    Parser (Command -> Options) -> Parser Command -> Parser Options
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Command
commands

commands :: Parser Command
commands :: Parser Command
commands =
  Mod CommandFields Command -> Parser Command
forall a. Mod CommandFields a -> Parser a
hsubparser
    ( FilePath -> ParserInfo Command -> Mod CommandFields Command
forall a. FilePath -> ParserInfo a -> Mod CommandFields a
command FilePath
"index" (Parser Command -> InfoMod Command -> ParserInfo Command
forall a. Parser a -> InfoMod a -> ParserInfo a
info (IndexOptions -> Command
Index (IndexOptions -> Command) -> Parser IndexOptions -> Parser Command
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser IndexOptions
indexCommand) (FilePath -> InfoMod Command
forall a. FilePath -> InfoMod a
progDesc FilePath
"Add a file to the repository"))
        Mod CommandFields Command
-> Mod CommandFields Command -> Mod CommandFields Command
forall a. Semigroup a => a -> a -> a
<> FilePath -> ParserInfo Command -> Mod CommandFields Command
forall a. FilePath -> ParserInfo a -> Mod CommandFields a
command FilePath
"query" (Parser Command -> InfoMod Command -> ParserInfo Command
forall a. Parser a -> InfoMod a -> ParserInfo a
info (QueryOptions -> Command
Query (QueryOptions -> Command) -> Parser QueryOptions -> Parser Command
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser QueryOptions
queryCommand) (FilePath -> InfoMod Command
forall a. FilePath -> InfoMod a
progDesc FilePath
"Add a file to the repository"))
    )

queryCommand :: Parser QueryOptions
queryCommand :: Parser QueryOptions
queryCommand =
  IpeId -> QueryOptions
QueryOptions
    (IpeId -> QueryOptions) -> Parser IpeId -> Parser QueryOptions
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ( Word64 -> IpeId
IpeId
            (Word64 -> IpeId) -> Parser Word64 -> Parser IpeId
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadM Word64 -> Mod ArgumentFields Word64 -> Parser Word64
forall a. ReadM a -> Mod ArgumentFields a -> Parser a
argument ReadM Word64
forall a. Read a => ReadM a
auto (FilePath -> Mod ArgumentFields Word64
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Find the info table provenance information for the given key" Mod ArgumentFields Word64
-> Mod ArgumentFields Word64 -> Mod ArgumentFields Word64
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod ArgumentFields Word64
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"INT")
        )

indexCommand :: Parser IndexOptions
indexCommand :: Parser IndexOptions
indexCommand =
  FilePath -> IndexOptions
IndexOptions
    (FilePath -> IndexOptions)
-> Parser FilePath -> Parser IndexOptions
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Mod ArgumentFields FilePath -> Parser FilePath
forall s. IsString s => Mod ArgumentFields s -> Parser s
strArgument (FilePath -> Mod ArgumentFields FilePath
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Eventlog location to index" Mod ArgumentFields FilePath
-> Mod ArgumentFields FilePath -> Mod ArgumentFields FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod ArgumentFields FilePath
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"FILENAME")