{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DuplicateRecordFields #-}

-- SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com
-- SPDX-License-Identifier: MIT

module CLI.Types where

import AST
import Control.Exception (Exception)
import Deps (Acyclic)
import Lining (LineFormat)
import Logger (LogLevel)
import Must (Must)
import Parser (Form)
import Sugar (SugarType)
import Text.Printf (printf)
import XMIR (XmirContext)

data PrintContext = PrintCtx
  { PrintContext -> SugarType
_sugar :: SugarType
  , PrintContext -> Bool
_hideRho :: Bool
  , PrintContext -> Maybe Int
_abridged :: Maybe Int
  , PrintContext -> Bool
_abridgedData :: Bool
  , PrintContext -> LineFormat
_line :: LineFormat
  , PrintContext -> Int
_margin :: Int
  , PrintContext -> XmirContext
_xmirCtx :: XmirContext
  , PrintContext -> Bool
_nonumber :: Bool
  , PrintContext -> Bool
_compress :: Bool
  , PrintContext -> Bool
_canonize :: Bool
  , PrintContext -> Bool
_sequence :: Bool
  , PrintContext -> Bool
_headers :: Bool
  , PrintContext -> Int
_meetPopularity :: Int
  , PrintContext -> Int
_meetLength :: Int
  , PrintContext -> Expression
_focus :: Expression
  , PrintContext -> Maybe String
_expression :: Maybe String
  , PrintContext -> Maybe String
_label :: Maybe String
  , PrintContext -> Maybe String
_meetPrefix :: Maybe String
  , PrintContext -> IOFormat
_outputFormat :: IOFormat
  }

data CmdException
  = InvalidCLIArguments String
  | CouldNotReadFromStdin String
  | CouldNotDataize
  | CouldNotPrintExpressionInXMIR
  | EmptySubstsOnMatch
  | AnonymousMetaInCondition String
  | UnboundMetaInCondition String
  | VersionMismatch String String
  | CouldNotCompile String
  | StaleEngine
  deriving (Show CmdException
Typeable CmdException
(Typeable CmdException, Show CmdException) =>
(CmdException -> SomeException)
-> (SomeException -> Maybe CmdException)
-> (CmdException -> String)
-> Exception CmdException
SomeException -> Maybe CmdException
CmdException -> String
CmdException -> SomeException
forall e.
(Typeable e, Show e) =>
(e -> SomeException)
-> (SomeException -> Maybe e) -> (e -> String) -> Exception e
$ctoException :: CmdException -> SomeException
toException :: CmdException -> SomeException
$cfromException :: SomeException -> Maybe CmdException
fromException :: SomeException -> Maybe CmdException
$cdisplayException :: CmdException -> String
displayException :: CmdException -> String
Exception)

instance Show CmdException where
  show :: CmdException -> String
show (InvalidCLIArguments String
msg) = String -> ShowS
forall r. PrintfType r => String -> r
printf String
"Invalid set of arguments: %s" String
msg
  show (CouldNotReadFromStdin String
msg) = String -> ShowS
forall r. PrintfType r => String -> r
printf String
"Could not read input from stdin\nReason: %s" String
msg
  show CmdException
CouldNotDataize = String
"Could not dataize given expression"
  show CmdException
CouldNotPrintExpressionInXMIR = String
"Could not print expression with --output=xmir, only expression printing is allowed"
  show CmdException
EmptySubstsOnMatch = String
"Provided pattern was not matched, no substitutions are built"
  show (AnonymousMetaInCondition String
kind) =
    String -> ShowS
forall r. PrintfType r => String -> r
printf String
"Anonymous meta '!%s' cannot be referenced in --when, only a named one can" String
kind
  show (UnboundMetaInCondition String
kind) =
    String -> ShowS
forall r. PrintfType r => String -> r
printf String
"The --when condition reads the meta '!%s' it never binds, since neither --pattern binds it" String
kind
  show (VersionMismatch String
expected String
actual) =
    String -> String -> ShowS
forall r. PrintfType r => String -> r
printf String
"Version mismatch: --pin requires '%s', but this is phino %s" String
expected String
actual
  show (CouldNotCompile String
reason) = String
reason
  show CmdException
StaleEngine = String
"The compiled rules are stale, since the rules of phino changed after 'phino compile', so run it again and rebuild"

data Command
  = CmdRewrite OptsRewrite
  | CmdDataize OptsDataize
  | CmdMorph OptsMorph
  | CmdExplain OptsExplain
  | CmdMerge OptsMerge
  | CmdMatch OptsMatch
  | CmdCompile OptsCompile

data Pin = PinVersion String | PinFile FilePath

data CliArgs = CliArgs
  { CliArgs -> Maybe Pin
_pin :: Maybe Pin
  , CliArgs -> Command
_command :: Command
  }

data IOFormat = XMIR | PHI | LATEX
  deriving (IOFormat -> IOFormat -> Bool
(IOFormat -> IOFormat -> Bool)
-> (IOFormat -> IOFormat -> Bool) -> Eq IOFormat
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: IOFormat -> IOFormat -> Bool
== :: IOFormat -> IOFormat -> Bool
$c/= :: IOFormat -> IOFormat -> Bool
/= :: IOFormat -> IOFormat -> Bool
Eq)

instance Show IOFormat where
  show :: IOFormat -> String
show IOFormat
XMIR = String
"xmir"
  show IOFormat
PHI = String
"phi"
  show IOFormat
LATEX = String
"latex"

data OptsDataize = OptsDataize
  { OptsDataize -> LogLevel
_logLevel :: LogLevel
  , OptsDataize -> Int
_logLines :: Int
  , OptsDataize -> IOFormat
_inputFormat :: IOFormat
  , OptsDataize -> Form
_monoform :: Form
  , OptsDataize -> IOFormat
_outputFormat :: IOFormat
  , OptsDataize -> SugarType
_sugarType :: SugarType
  , OptsDataize -> Bool
_hideRho :: Bool
  , OptsDataize -> LineFormat
_flat :: LineFormat
  , OptsDataize -> Bool
_omitListing :: Bool
  , OptsDataize -> Bool
_omitComments :: Bool
  , OptsDataize -> Bool
_nonumber :: Bool
  , OptsDataize -> Bool
_sequence :: Bool
  , OptsDataize -> Bool
_headers :: Bool
  , OptsDataize -> Bool
_canonize :: Bool
  , OptsDataize -> Bool
_depthSensitive :: Bool
  , OptsDataize -> Bool
_shuffle :: Bool
  , OptsDataize -> Int
_seed :: Int
  , OptsDataize -> Bool
_quiet :: Bool
  , OptsDataize -> Bool
_partial :: Bool
  , OptsDataize -> Maybe Acyclic
_acyclic :: Maybe Acyclic
  , OptsDataize -> Int
_maxLoops :: Int
  , OptsDataize -> Bool
_compress :: Bool
  , OptsDataize -> Int
_maxDepth :: Int
  , OptsDataize -> Int
_maxCycles :: Int
  , OptsDataize -> Int
_maxSteps :: Int
  , OptsDataize -> Maybe Int
_maxFirings :: Maybe Int
  , OptsDataize -> Maybe Int
_maxSeconds :: Maybe Int
  , OptsDataize -> Int
_margin :: Int
  , OptsDataize -> Maybe Int
_meetPopularity :: Maybe Int
  , OptsDataize -> Maybe Int
_meetLength :: Maybe Int
  , OptsDataize -> [String]
_hide :: [String]
  , OptsDataize -> [String]
_show :: [String]
  , OptsDataize -> String
_locator :: String
  , OptsDataize -> String
_focus :: String
  , OptsDataize -> Maybe String
_expression :: Maybe String
  , OptsDataize -> Maybe String
_label :: Maybe String
  , OptsDataize -> Maybe String
_meetPrefix :: Maybe String
  , OptsDataize -> Maybe String
_inside :: Maybe String
  , OptsDataize -> Maybe String
_stepsDir :: Maybe FilePath
  , OptsDataize -> Maybe String
_protocol :: Maybe FilePath
  , OptsDataize -> Maybe Int
_abridged :: Maybe Int
  , OptsDataize -> Bool
_abridgedData :: Bool
  , OptsDataize -> Maybe String
_symbolic :: Maybe FilePath
  , OptsDataize -> Maybe String
_inputFile :: Maybe FilePath
  }

data OptsMorph = OptsMorph
  { OptsMorph -> LogLevel
_logLevel :: LogLevel
  , OptsMorph -> Int
_logLines :: Int
  , OptsMorph -> IOFormat
_inputFormat :: IOFormat
  , OptsMorph -> Form
_monoform :: Form
  , OptsMorph -> IOFormat
_outputFormat :: IOFormat
  , OptsMorph -> SugarType
_sugarType :: SugarType
  , OptsMorph -> Bool
_hideRho :: Bool
  , OptsMorph -> LineFormat
_flat :: LineFormat
  , OptsMorph -> Bool
_omitListing :: Bool
  , OptsMorph -> Bool
_omitComments :: Bool
  , OptsMorph -> Bool
_nonumber :: Bool
  , OptsMorph -> Bool
_sequence :: Bool
  , OptsMorph -> Bool
_headers :: Bool
  , OptsMorph -> Bool
_canonize :: Bool
  , OptsMorph -> Bool
_depthSensitive :: Bool
  , OptsMorph -> Bool
_shuffle :: Bool
  , OptsMorph -> Int
_seed :: Int
  , OptsMorph -> Bool
_quiet :: Bool
  , OptsMorph -> Bool
_partial :: Bool
  , OptsMorph -> Maybe Acyclic
_acyclic :: Maybe Acyclic
  , OptsMorph -> Int
_maxLoops :: Int
  , OptsMorph -> Bool
_compress :: Bool
  , OptsMorph -> Int
_maxDepth :: Int
  , OptsMorph -> Int
_maxCycles :: Int
  , OptsMorph -> Int
_maxSteps :: Int
  , OptsMorph -> Maybe Int
_maxFirings :: Maybe Int
  , OptsMorph -> Maybe Int
_maxSeconds :: Maybe Int
  , OptsMorph -> Int
_margin :: Int
  , OptsMorph -> Maybe Int
_meetPopularity :: Maybe Int
  , OptsMorph -> Maybe Int
_meetLength :: Maybe Int
  , OptsMorph -> [String]
_hide :: [String]
  , OptsMorph -> [String]
_show :: [String]
  , OptsMorph -> String
_locator :: String
  , OptsMorph -> String
_focus :: String
  , OptsMorph -> Maybe String
_expression :: Maybe String
  , OptsMorph -> Maybe String
_label :: Maybe String
  , OptsMorph -> Maybe String
_meetPrefix :: Maybe String
  , OptsMorph -> Maybe String
_inside :: Maybe String
  , OptsMorph -> Maybe String
_stepsDir :: Maybe FilePath
  , OptsMorph -> Maybe String
_protocol :: Maybe FilePath
  , OptsMorph -> Maybe Int
_abridged :: Maybe Int
  , OptsMorph -> Bool
_abridgedData :: Bool
  , OptsMorph -> Maybe String
_symbolic :: Maybe FilePath
  , OptsMorph -> Maybe String
_inputFile :: Maybe FilePath
  }

data OptsExplain = OptsExplain
  { OptsExplain -> LogLevel
_logLevel :: LogLevel
  , OptsExplain -> Int
_logLines :: Int
  , OptsExplain -> [String]
_rules :: [FilePath]
  , OptsExplain -> Bool
_normalize :: Bool
  , OptsExplain -> Bool
_morph :: Bool
  , OptsExplain -> Bool
_dataize :: Bool
  , OptsExplain -> Bool
_contextualize :: Bool
  , OptsExplain -> Bool
_shuffle :: Bool
  , OptsExplain -> Int
_seed :: Int
  , OptsExplain -> Maybe String
_targetFile :: Maybe FilePath
  }

data OptsRewrite = OptsRewrite
  { OptsRewrite -> LogLevel
_logLevel :: LogLevel
  , OptsRewrite -> Int
_logLines :: Int
  , OptsRewrite -> IOFormat
_inputFormat :: IOFormat
  , OptsRewrite -> Form
_monoform :: Form
  , OptsRewrite -> IOFormat
_outputFormat :: IOFormat
  , OptsRewrite -> SugarType
_sugarType :: SugarType
  , OptsRewrite -> Bool
_hideRho :: Bool
  , OptsRewrite -> LineFormat
_flat :: LineFormat
  , OptsRewrite -> Must
_must :: Must
  , OptsRewrite -> Bool
_normalize :: Bool
  , OptsRewrite -> Bool
_shuffle :: Bool
  , OptsRewrite -> Int
_seed :: Int
  , OptsRewrite -> Bool
_omitListing :: Bool
  , OptsRewrite -> Bool
_omitComments :: Bool
  , OptsRewrite -> Bool
_depthSensitive :: Bool
  , OptsRewrite -> Bool
_nonumber :: Bool
  , OptsRewrite -> Bool
_inPlace :: Bool
  , OptsRewrite -> Bool
_update :: Bool
  , OptsRewrite -> Bool
_sequence :: Bool
  , OptsRewrite -> Bool
_headers :: Bool
  , OptsRewrite -> Bool
_canonize :: Bool
  , OptsRewrite -> Bool
_compress :: Bool
  , OptsRewrite -> Int
_maxDepth :: Int
  , OptsRewrite -> Int
_maxCycles :: Int
  , OptsRewrite -> Int
_margin :: Int
  , OptsRewrite -> Maybe Int
_meetPopularity :: Maybe Int
  , OptsRewrite -> Maybe Int
_meetLength :: Maybe Int
  , OptsRewrite -> [String]
_rules :: [FilePath]
  , OptsRewrite -> [String]
_hide :: [String]
  , OptsRewrite -> [String]
_show :: [String]
  , OptsRewrite -> String
_locator :: String
  , OptsRewrite -> String
_focus :: String
  , OptsRewrite -> Maybe String
_expression :: Maybe String
  , OptsRewrite -> Maybe String
_label :: Maybe String
  , OptsRewrite -> Maybe String
_meetPrefix :: Maybe String
  , OptsRewrite -> Maybe String
_breakpoint :: Maybe String
  , OptsRewrite -> Maybe String
_targetFile :: Maybe FilePath
  , OptsRewrite -> Maybe String
_stepsDir :: Maybe FilePath
  , OptsRewrite -> Maybe String
_inputFile :: Maybe FilePath
  }

data OptsMerge = OptsMerge
  { OptsMerge -> LogLevel
_logLevel :: LogLevel
  , OptsMerge -> Int
_logLines :: Int
  , OptsMerge -> IOFormat
_inputFormat :: IOFormat
  , OptsMerge -> Form
_monoform :: Form
  , OptsMerge -> IOFormat
_outputFormat :: IOFormat
  , OptsMerge -> SugarType
_sugarType :: SugarType
  , OptsMerge -> LineFormat
_flat :: LineFormat
  , OptsMerge -> Bool
_omitListing :: Bool
  , OptsMerge -> Bool
_omitComments :: Bool
  , OptsMerge -> Int
_margin :: Int
  , OptsMerge -> Maybe String
_targetFile :: Maybe FilePath
  , OptsMerge -> [String]
_inputs :: [FilePath]
  , OptsMerge -> Int
_seed :: Int
  }

data OptsMatch = OptsMatch
  { OptsMatch -> LogLevel
_logLevel :: LogLevel
  , OptsMatch -> Int
_logLines :: Int
  , OptsMatch -> Form
_monoform :: Form
  , OptsMatch -> SugarType
_sugarType :: SugarType
  , OptsMatch -> LineFormat
_flat :: LineFormat
  , OptsMatch -> Maybe String
_pattern :: Maybe String
  , OptsMatch -> Maybe String
_when :: Maybe String
  , OptsMatch -> Maybe String
_inputFile :: Maybe FilePath
  , OptsMatch -> Int
_seed :: Int
  }

data OptsCompile = OptsCompile
  { OptsCompile -> LogLevel
_logLevel :: LogLevel
  , OptsCompile -> Int
_logLines :: Int
  , OptsCompile -> [String]
_rules :: [FilePath]
  , OptsCompile -> String
_targetFile :: FilePath
  }