content: {-# LANGUAGE DeriveDataTypeable, RecordWildCards #-}
  {-# OPTIONS_GHC -fno-warn-missing-fields -fno-cse #-}
  
  module Action.CmdLine(
      CmdLine(..), Language(..),
      getCmdLine, defaultDatabaseLang,
      defaultGenerate,
      whenLoud, whenNormal
      ) where
  
  import Data.List.Extra
  import Data.Version
  import General.Util
  import Paths_hoogle (version)
  import System.Console.CmdArgs
  import System.Directory
  import System.Environment
  import System.FilePath
  
  data Language = Haskell | Frege deriving (Data,Typeable,Show,Eq,Enum,Bounded)
  
  data CmdLine
      = Search
          {color :: Maybe Bool
          ,json :: Bool
          ,jsonl :: Bool
          ,link :: Bool
          ,numbers :: Bool
          ,info :: Bool
          ,database :: FilePath
          ,count :: Maybe Int
          ,query :: [String]
          ,repeat_ :: Int
          ,language :: Language
          ,compare_ :: [String]
          }
      | Generate
          {download :: Maybe Bool
          ,database :: FilePath
          ,insecure :: Bool
          ,include :: [String]
          ,count :: Maybe Int
          ,local_ :: [FilePath]
          ,haddock :: Maybe FilePath
          ,debug :: Bool
          ,language :: Language
          }
      | Server
          {port :: Int
          ,database :: FilePath
          ,cdn :: String
          ,logs :: FilePath
          ,local :: Bool
          ,haddock :: Maybe FilePath
          ,links :: Bool
          ,language :: Language
          ,scope :: String
          ,home :: String
          ,host :: String
          ,https :: Bool
          ,cert :: FilePath
          ,key :: FilePath
          ,datadir :: Maybe FilePath
          ,no_security_headers :: Bool
          }
      | Replay
          {logs :: FilePath
          ,database :: FilePath
          ,repeat_ :: Int
          ,language :: Language
          ,scope :: String
          }
      | Test
          { deep :: Bool
          , disable_network_tests  :: Bool
          , database :: FilePath
          , language :: Language
          }
        deriving (Data,Typeable,Show)
  
  defaultDatabaseLang :: Language -> IO FilePath
  defaultDatabaseLang lang = do
      dir <- getAppUserDataDirectory "hoogle"
      pure $ dir </> "default-" ++ lower (show lang) ++ "-" ++ showVersion (trimVersion 3 version) ++ ".hoo"
  
  getCmdLine :: [String] -> IO CmdLine
  getCmdLine args = do
      args <- withArgs args $ cmdArgsRun cmdLineMode
  
      -- fill in the default database
      args <- if database args /= "" then pure args else do
          db <- defaultDatabaseLang $ language args; pure args{database=db}
  
      -- fix up people using Hoogle 4 instructions
      args <- case args of
          Generate{..} | "all" `elem` include -> do
              putStrLn "Warning: 'all' argument is no longer required, and has been ignored."
              pure $ args{include = delete "all" include}
          _ -> pure args
  
      pure args
  
  
  defaultGenerate :: CmdLine
  defaultGenerate = generate{language=Haskell}
  
  
  cmdLineMode = cmdArgsMode $ modes [search_ &= auto,generate,server,replay,test]
      &= verbosity &= program "hoogle"
      &= summary ("Hoogle " ++ showVersion version ++ ", https://hoogle.haskell.org/")
  
  search_ = Search
      {color = def &= name "colour" &= help "Use colored output (requires ANSI terminal)"
      ,json = def &= name "json" &= help "Get result as JSON"
      ,jsonl = def &= name "jsonl" &= help "Get result as JSONL (JSON Lines)"
      ,link = def &= help "Give URL's for each result"
      ,numbers = def &= help "Give counter for each result"
      ,info = def &= help "Give extended information about the first result"
      ,database = def &= typFile &= help "Name of database to use (use .hoo extension)"
      ,count = Nothing &= name "n" &= help "Maximum number of results to return (defaults to 10)"
      ,query = def &= args &= typ "QUERY"
      ,repeat_ = 1 &= help "Number of times to repeat (for benchmarking)"
      ,language = enum [x &= explicit &= name (lower $ show x) &= help ("Work with " ++ show x) | x <- enumerate] &= groupname "Language"
      ,compare_ = def &= help "Type signatures to compare against"
      } &= help "Perform a search"
  
  generate = Generate
      {download = def &= help "Download all files from the web"
      ,insecure = def &= help "Allow insecure HTTPS connections"
      ,include = def &= args &= typ "PACKAGE"
      ,local_ = def &= opt "" &= help "Index local packages and link to local haddock docs"
      ,count = Nothing &= name "n" &= help "Maximum number of packages to index (defaults to all)"
      ,haddock = def &= help "Use local haddocks"
      ,debug = def &= help "Generate debug information"
      } &= help "Generate Hoogle databases"
  
  server = Server
      {port = 8080 &= typ "INT" &= help "Port number"
      ,cdn = "" &= typ "URL" &= help "URL prefix to use"
      ,logs = "" &= opt "log.txt" &= typFile &= help "File to log requests to (defaults to stdout)"
      ,local = False &= help "Allow following file:// links, restricts to 127.0.0.1  Set --host explicitely (including to '*' for any host) to override the localhost-only behaviour"
      ,haddock = def &= help "Serve local haddocks from a specified directory"
      ,scope = def &= help "Default scope to start with"
      ,links = def &= help "Display extra links"
      ,home = "https://hoogle.haskell.org" &= typ "URL" &= help "Set the URL linked to by the Hoogle logo."
      ,host = "" &= help "Set the host to bind on (e.g., an ip address; '!4' for ipv4-only; '!6' for ipv6-only; default: '*' for any host)."
      ,https = def &= help "Start an https server (use --cert and --key to specify paths to the .pem files)"
      ,cert = "cert.pem" &= typFile &= help "Path to the certificate pem file (when running an https server)"
      ,key = "key.pem" &= typFile &= help "Path to the key pem file (when running an https server)"
      ,datadir = def &= help "Override data directory paths"
      ,no_security_headers = False &= help "Don't send CSP security headers"
      } &= help "Start a Hoogle server"
  
  replay = Replay
      {logs = "log.txt" &= args &= typ "FILE"
      } &= help "Replay a log file"
  
  test = Test
      { deep    = False &= help "Run extra long tests"
      , disable_network_tests = False  &= help "Disables the use of network tests"
      } &= help "Run the test suite"
  