module WebDriverPreCore.BiDi.Command
  ( Command (..),
    CommandMethod (..),
    KnownCommand (..),
    OffSpecCommand (..),
    mkCommand,
    emptyCommand,
    mkOffSpecCommand,
    extendLoosenCommand,
    extendCommand,
    extendCoerceCommand,
    loosenCommand,
    coerceCommand,
    knownCommandToText,
    toCommandText,
  )
where

import AesonUtils (jsonToText, objectOrThrow)
import Control.Applicative (Alternative (..))
import Data.Aeson
  ( Object,
    ToJSON,
    Value (..),
  )
import Data.Aeson.KeyMap qualified as KM
import Data.Aeson.Types (FromJSON (parseJSON), Parser, ToJSON (..))
import Data.Text as T (Text, intercalate, unpack)
import Utils (enumerate)

-- |  A BiDi Command to be sent over the WebSocket connection.
--
-- All functions in "WebDriverPreCore.BiDi.API" return values of this type.
--
-- The command contains the method name and parameters to be serialized as JSON and a phantom response type @r@, which is always an instance of 'FromJSON'.
data Command r = MkCommand
  { -- | An identifier for the command to be invoked
    forall {k} (r :: k). Command r -> CommandMethod
method :: CommandMethod,
    -- | The JSON payload to be sent
    forall {k} (r :: k). Command r -> Object
params :: Object
  }
  deriving (Int -> Command r -> ShowS
[Command r] -> ShowS
Command r -> String
(Int -> Command r -> ShowS)
-> (Command r -> String)
-> ([Command r] -> ShowS)
-> Show (Command r)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall k (r :: k). Int -> Command r -> ShowS
forall k (r :: k). [Command r] -> ShowS
forall k (r :: k). Command r -> String
$cshowsPrec :: forall k (r :: k). Int -> Command r -> ShowS
showsPrec :: Int -> Command r -> ShowS
$cshow :: forall k (r :: k). Command r -> String
show :: Command r -> String
$cshowList :: forall k (r :: k). [Command r] -> ShowS
showList :: [Command r] -> ShowS
Show, Command r -> Command r -> Bool
(Command r -> Command r -> Bool)
-> (Command r -> Command r -> Bool) -> Eq (Command r)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall k (r :: k). Command r -> Command r -> Bool
$c== :: forall k (r :: k). Command r -> Command r -> Bool
== :: Command r -> Command r -> Bool
$c/= :: forall k (r :: k). Command r -> Command r -> Bool
/= :: Command r -> Command r -> Bool
Eq)

-- | The method name of a BiDi command.
--
-- This library provides known commands as 'KnownCommand' values, but users can also create off-spec commands using 'OffSpecCommand' as a fallback, when the driver supports commands not yet implemented in this library.
data CommandMethod
  = KnownCommand KnownCommand
  | OffSpecCommand OffSpecCommand
  deriving (Int -> CommandMethod -> ShowS
[CommandMethod] -> ShowS
CommandMethod -> String
(Int -> CommandMethod -> ShowS)
-> (CommandMethod -> String)
-> ([CommandMethod] -> ShowS)
-> Show CommandMethod
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CommandMethod -> ShowS
showsPrec :: Int -> CommandMethod -> ShowS
$cshow :: CommandMethod -> String
show :: CommandMethod -> String
$cshowList :: [CommandMethod] -> ShowS
showList :: [CommandMethod] -> ShowS
Show, CommandMethod -> CommandMethod -> Bool
(CommandMethod -> CommandMethod -> Bool)
-> (CommandMethod -> CommandMethod -> Bool) -> Eq CommandMethod
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CommandMethod -> CommandMethod -> Bool
== :: CommandMethod -> CommandMethod -> Bool
$c/= :: CommandMethod -> CommandMethod -> Bool
/= :: CommandMethod -> CommandMethod -> Bool
Eq)

instance ToJSON CommandMethod where
  toJSON :: CommandMethod -> Value
  toJSON :: CommandMethod -> Value
toJSON = Text -> Value
String (Text -> Value)
-> (CommandMethod -> Text) -> CommandMethod -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CommandMethod -> Text
toCommandText

-- | This type enumerates the BiDi commands known to this library.
data KnownCommand
  = BrowserClose
  | BrowserCreateUserContext
  | BrowserGetClientWindows
  | BrowserGetUserContexts
  | BrowserRemoveUserContext
  | BrowserSetClientWindowState
  | BrowserSetDownloadBehavior
  | BrowsingContextActivate
  | BrowsingContextCaptureScreenshot
  | BrowsingContextClose
  | BrowsingContextCreate
  | BrowsingContextGetTree
  | BrowsingContextHandleUserPrompt
  | BrowsingContextLocateNodes
  | BrowsingContextNavigate
  | BrowsingContextPrint
  | BrowsingContextReload
  | BrowsingContextSetViewport
  | BrowsingContextTraverseHistory
  | EmulationSetForcedColorsModeThemeOverride
  | EmulationSetGeolocationOverride
  | EmulationSetLocaleOverride
  | EmulationSetNetworkConditions
  | EmulationSetScreenOrientationOverride
  | EmulationSetScreenSettingsOverride
  | EmulationSetScriptingEnabled
  | EmulationSetTimezoneOverride
  | EmulationSetTouchOverride
  | EmulationSetUserAgentOverride
  | InputPerformActions
  | InputReleaseActions
  | InputSetFiles
  | NetworkAddDataCollector
  | NetworkAddIntercept
  | NetworkContinueRequest
  | NetworkContinueResponse
  | NetworkContinueWithAuth
  | NetworkDisownData
  | NetworkFailRequest
  | NetworkGetData
  | NetworkProvideResponse
  | NetworkRemoveDataCollector
  | NetworkRemoveIntercept
  | NetworkSetCacheBehavior
  | NetworkSetExtraHeaders
  | ScriptAddPreloadScript
  | ScriptCallFunction
  | ScriptDisown
  | ScriptEvaluate
  | ScriptGetRealms
  | ScriptRemovePreloadScript
  | SessionEnd
  | SessionNew
  | SessionStatus
  | SessionSubscribe
  | SessionUnsubscribe
  | StorageDeleteCookies
  | StorageGetCookies
  | StorageSetCookie
  | WebExtensionInstall
  | WebExtensionUninstall
  deriving (Int -> KnownCommand -> ShowS
[KnownCommand] -> ShowS
KnownCommand -> String
(Int -> KnownCommand -> ShowS)
-> (KnownCommand -> String)
-> ([KnownCommand] -> ShowS)
-> Show KnownCommand
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> KnownCommand -> ShowS
showsPrec :: Int -> KnownCommand -> ShowS
$cshow :: KnownCommand -> String
show :: KnownCommand -> String
$cshowList :: [KnownCommand] -> ShowS
showList :: [KnownCommand] -> ShowS
Show, KnownCommand -> KnownCommand -> Bool
(KnownCommand -> KnownCommand -> Bool)
-> (KnownCommand -> KnownCommand -> Bool) -> Eq KnownCommand
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: KnownCommand -> KnownCommand -> Bool
== :: KnownCommand -> KnownCommand -> Bool
$c/= :: KnownCommand -> KnownCommand -> Bool
/= :: KnownCommand -> KnownCommand -> Bool
Eq, Int -> KnownCommand
KnownCommand -> Int
KnownCommand -> [KnownCommand]
KnownCommand -> KnownCommand
KnownCommand -> KnownCommand -> [KnownCommand]
KnownCommand -> KnownCommand -> KnownCommand -> [KnownCommand]
(KnownCommand -> KnownCommand)
-> (KnownCommand -> KnownCommand)
-> (Int -> KnownCommand)
-> (KnownCommand -> Int)
-> (KnownCommand -> [KnownCommand])
-> (KnownCommand -> KnownCommand -> [KnownCommand])
-> (KnownCommand -> KnownCommand -> [KnownCommand])
-> (KnownCommand -> KnownCommand -> KnownCommand -> [KnownCommand])
-> Enum KnownCommand
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: KnownCommand -> KnownCommand
succ :: KnownCommand -> KnownCommand
$cpred :: KnownCommand -> KnownCommand
pred :: KnownCommand -> KnownCommand
$ctoEnum :: Int -> KnownCommand
toEnum :: Int -> KnownCommand
$cfromEnum :: KnownCommand -> Int
fromEnum :: KnownCommand -> Int
$cenumFrom :: KnownCommand -> [KnownCommand]
enumFrom :: KnownCommand -> [KnownCommand]
$cenumFromThen :: KnownCommand -> KnownCommand -> [KnownCommand]
enumFromThen :: KnownCommand -> KnownCommand -> [KnownCommand]
$cenumFromTo :: KnownCommand -> KnownCommand -> [KnownCommand]
enumFromTo :: KnownCommand -> KnownCommand -> [KnownCommand]
$cenumFromThenTo :: KnownCommand -> KnownCommand -> KnownCommand -> [KnownCommand]
enumFromThenTo :: KnownCommand -> KnownCommand -> KnownCommand -> [KnownCommand]
Enum, KnownCommand
KnownCommand -> KnownCommand -> Bounded KnownCommand
forall a. a -> a -> Bounded a
$cminBound :: KnownCommand
minBound :: KnownCommand
$cmaxBound :: KnownCommand
maxBound :: KnownCommand
Bounded)

-- | The method name of a BiDi command not yet implemented in this library
newtype OffSpecCommand = MkOffSpecCommand {OffSpecCommand -> Text
command :: Text}
  deriving (Int -> OffSpecCommand -> ShowS
[OffSpecCommand] -> ShowS
OffSpecCommand -> String
(Int -> OffSpecCommand -> ShowS)
-> (OffSpecCommand -> String)
-> ([OffSpecCommand] -> ShowS)
-> Show OffSpecCommand
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> OffSpecCommand -> ShowS
showsPrec :: Int -> OffSpecCommand -> ShowS
$cshow :: OffSpecCommand -> String
show :: OffSpecCommand -> String
$cshowList :: [OffSpecCommand] -> ShowS
showList :: [OffSpecCommand] -> ShowS
Show, OffSpecCommand -> OffSpecCommand -> Bool
(OffSpecCommand -> OffSpecCommand -> Bool)
-> (OffSpecCommand -> OffSpecCommand -> Bool) -> Eq OffSpecCommand
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: OffSpecCommand -> OffSpecCommand -> Bool
== :: OffSpecCommand -> OffSpecCommand -> Bool
$c/= :: OffSpecCommand -> OffSpecCommand -> Bool
/= :: OffSpecCommand -> OffSpecCommand -> Bool
Eq)
  deriving newtype (Maybe OffSpecCommand
Value -> Parser [OffSpecCommand]
Value -> Parser OffSpecCommand
(Value -> Parser OffSpecCommand)
-> (Value -> Parser [OffSpecCommand])
-> Maybe OffSpecCommand
-> FromJSON OffSpecCommand
forall a.
(Value -> Parser a)
-> (Value -> Parser [a]) -> Maybe a -> FromJSON a
$cparseJSON :: Value -> Parser OffSpecCommand
parseJSON :: Value -> Parser OffSpecCommand
$cparseJSONList :: Value -> Parser [OffSpecCommand]
parseJSONList :: Value -> Parser [OffSpecCommand]
$comittedField :: Maybe OffSpecCommand
omittedField :: Maybe OffSpecCommand
FromJSON, [OffSpecCommand] -> Value
[OffSpecCommand] -> Encoding
OffSpecCommand -> Bool
OffSpecCommand -> Value
OffSpecCommand -> Encoding
(OffSpecCommand -> Value)
-> (OffSpecCommand -> Encoding)
-> ([OffSpecCommand] -> Value)
-> ([OffSpecCommand] -> Encoding)
-> (OffSpecCommand -> Bool)
-> ToJSON OffSpecCommand
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
$ctoJSON :: OffSpecCommand -> Value
toJSON :: OffSpecCommand -> Value
$ctoEncoding :: OffSpecCommand -> Encoding
toEncoding :: OffSpecCommand -> Encoding
$ctoJSONList :: [OffSpecCommand] -> Value
toJSONList :: [OffSpecCommand] -> Value
$ctoEncodingList :: [OffSpecCommand] -> Encoding
toEncodingList :: [OffSpecCommand] -> Encoding
$comitField :: OffSpecCommand -> Bool
omitField :: OffSpecCommand -> Bool
ToJSON)

-- constructors

-- | Creates a 'Command' with the given 'KnownCommand' method and parameters.
--
-- Patially applied in "WebDriverPreCore.BiDi.API" to generate specific named command functions which accept only an input type, relevant to that command.
-- The input type must be an instance of 'ToJSON' and encode to a JSON 'Object' type.
--
-- E.g. the 'WebDriverPreCore.BiDi.API.browsingContextNavigate', which takes a 'Navigate' input and returns a 'Command' with a 'NavigateResult' output, is defined by the partial application of 'mkCommand':
--
-- @
-- browsingContextNavigate :: Navigate -> Command NavigateResult
-- browsingContextNavigate = mkCommand BrowsingContextNavigate
-- @
mkCommand ::
  forall c r.
  (ToJSON c) =>
  -- | The identitifier for the command to be invoked
  KnownCommand ->
  -- | The parameters to be sent with the command
  c ->
  -- | A 'Command' value with the given method and parameters
  Command r
mkCommand :: forall {k} c (r :: k). ToJSON c => KnownCommand -> c -> Command r
mkCommand KnownCommand
method c
params = MkCommand {method :: CommandMethod
method = KnownCommand -> CommandMethod
KnownCommand KnownCommand
method, params :: Object
params = Text -> c -> Object
forall a. ToJSON a => Text -> a -> Object
objectOrThrow (Text
"mkCommand - " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> CommandMethod -> Text
toCommandText (KnownCommand -> CommandMethod
KnownCommand KnownCommand
method)) c
params}

-- | Creates a 'Command' with the given 'KnownCommand' method and no parameters.
-- This is the same as calling 'mkCommand' with an empty object as parameters.
--
-- E.g. the 'WebDriverPreCore.BiDi.API.browserGetClientWindows', which takes no input and returns a 'Command' with a list of 'WindowInfo' output, is defined by the partial application of 'emptyCommand':
--
-- @
-- browserGetClientWindows :: Command [WindowInfo]
-- browserGetClientWindows = emptyCommand BrowserGetClientWindows
-- @
emptyCommand ::
  forall r.
  -- | The identitifier for the command to be invoked
  KnownCommand ->
  -- | A 'Command' value with the given method and no parameters
  Command r
emptyCommand :: forall {k} (r :: k). KnownCommand -> Command r
emptyCommand KnownCommand
method = MkCommand {method :: CommandMethod
method = KnownCommand -> CommandMethod
KnownCommand KnownCommand
method, params :: Object
params = Object
forall v. KeyMap v
KM.empty}

-- fallback modifiers

-- | Creates a 'Command' with the given method name text, JSON Object parameters, and an expected JSON Object response.
mkOffSpecCommand :: Text -> Object -> Command Object
mkOffSpecCommand :: Text -> Object -> Command Object
mkOffSpecCommand Text
method = CommandMethod -> Object -> Command Object
forall {k} (r :: k). CommandMethod -> Object -> Command r
MkCommand (OffSpecCommand -> CommandMethod
OffSpecCommand (OffSpecCommand -> CommandMethod)
-> OffSpecCommand -> CommandMethod
forall a b. (a -> b) -> a -> b
$ Text -> OffSpecCommand
MkOffSpecCommand Text
method)

-- | Extends the parameters of a 'Command' with additional fields from a JSON 'Object', changing the expected response type to a generic JSON 'Value'.
extendLoosenCommand :: forall r. Object -> Command r -> Command Value
extendLoosenCommand :: forall {k} (r :: k). Object -> Command r -> Command Value
extendLoosenCommand = Object -> Command r -> Command Value
forall {k} {k} (r :: k) (r2 :: k).
Object -> Command r -> Command r2
extendCoerceCommand

-- | Extends the parameters of a 'Command' with additional fields from a JSON 'Object', preserving the expected response type.
extendCommand :: forall r. Object -> Command r -> Command r
extendCommand :: forall {k} (r :: k). Object -> Command r -> Command r
extendCommand = Object -> Command r -> Command r
forall {k} {k} (r :: k) (r2 :: k).
Object -> Command r -> Command r2
extendCoerceCommand

-- | Extends the parameters of a 'Command' with additional fields from a JSON 'Object', changing the expected response type to a different type.
extendCoerceCommand :: forall r r2. Object -> Command r -> Command r2
extendCoerceCommand :: forall {k} {k} (r :: k) (r2 :: k).
Object -> Command r -> Command r2
extendCoerceCommand Object
extended MkCommand {CommandMethod
method :: forall {k} (r :: k). Command r -> CommandMethod
method :: CommandMethod
method, Object
params :: forall {k} (r :: k). Command r -> Object
params :: Object
params} =
  MkCommand
    { CommandMethod
method :: CommandMethod
method :: CommandMethod
method,
      params :: Object
params = Object
params Object -> Object -> Object
forall a. Semigroup a => a -> a -> a
<> Object
extended
    }

-- | Changes the expected response type of a 'Command' to a generic JSON 'Value'.
loosenCommand :: forall r. Command r -> Command Value
loosenCommand :: forall {k} (r :: k). Command r -> Command Value
loosenCommand = Command r -> Command Value
forall {k} {k} (r :: k) (r' :: k). Command r -> Command r'
coerceCommand

-- | Changes the expected response type of a 'Command' to a different type.
coerceCommand :: forall r r'. Command r -> Command r'
coerceCommand :: forall {k} {k} (r :: k) (r' :: k). Command r -> Command r'
coerceCommand MkCommand {CommandMethod
method :: forall {k} (r :: k). Command r -> CommandMethod
method :: CommandMethod
method, Object
params :: forall {k} (r :: k). Command r -> Object
params :: Object
params} = MkCommand {CommandMethod
method :: CommandMethod
method :: CommandMethod
method, Object
params :: Object
params :: Object
params}

instance ToJSON KnownCommand where
  toJSON :: KnownCommand -> Value
  toJSON :: KnownCommand -> Value
toJSON = Text -> Value
String (Text -> Value) -> (KnownCommand -> Text) -> KnownCommand -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. KnownCommand -> Text
knownCommandToText

instance FromJSON KnownCommand where
  parseJSON :: Value -> Parser KnownCommand
  parseJSON :: Value -> Parser KnownCommand
parseJSON =
    \case
      String Text
c -> case Text
c of
        Text
"browser.close" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
BrowserClose
        Text
"browser.createUserContext" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
BrowserCreateUserContext
        Text
"browser.getClientWindows" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
BrowserGetClientWindows
        Text
"browser.getUserContexts" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
BrowserGetUserContexts
        Text
"browser.removeUserContext" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
BrowserRemoveUserContext
        Text
"browser.setClientWindowState" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
BrowserSetClientWindowState
        Text
"browser.setDownloadBehavior" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
BrowserSetDownloadBehavior
        Text
"browsingContext.activate" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
BrowsingContextActivate
        Text
"browsingContext.captureScreenshot" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
BrowsingContextCaptureScreenshot
        Text
"browsingContext.close" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
BrowsingContextClose
        Text
"browsingContext.create" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
BrowsingContextCreate
        Text
"browsingContext.getTree" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
BrowsingContextGetTree
        Text
"browsingContext.handleUserPrompt" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
BrowsingContextHandleUserPrompt
        Text
"browsingContext.locateNodes" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
BrowsingContextLocateNodes
        Text
"browsingContext.navigate" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
BrowsingContextNavigate
        Text
"browsingContext.print" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
BrowsingContextPrint
        Text
"browsingContext.reload" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
BrowsingContextReload
        Text
"browsingContext.setViewport" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
BrowsingContextSetViewport
        Text
"browsingContext.traverseHistory" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
BrowsingContextTraverseHistory
        Text
"emulation.setForcedColorsModeThemeOverride" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
EmulationSetForcedColorsModeThemeOverride
        Text
"emulation.setGeolocationOverride" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
EmulationSetGeolocationOverride
        Text
"emulation.setLocaleOverride" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
EmulationSetLocaleOverride
        Text
"emulation.setNetworkConditions" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
EmulationSetNetworkConditions
        Text
"emulation.setScreenOrientationOverride" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
EmulationSetScreenOrientationOverride
        Text
"emulation.setScreenSettingsOverride" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
EmulationSetScreenSettingsOverride
        Text
"emulation.setScriptingEnabled" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
EmulationSetScriptingEnabled
        Text
"emulation.setTimezoneOverride" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
EmulationSetTimezoneOverride
        Text
"emulation.setTouchOverride" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
EmulationSetTouchOverride
        Text
"emulation.setUserAgentOverride" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
EmulationSetUserAgentOverride
        Text
"input.performActions" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
InputPerformActions
        Text
"input.releaseActions" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
InputReleaseActions
        Text
"input.setFiles" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
InputSetFiles
        Text
"network.addDataCollector" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
NetworkAddDataCollector
        Text
"network.addIntercept" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
NetworkAddIntercept
        Text
"network.continueRequest" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
NetworkContinueRequest
        Text
"network.continueResponse" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
NetworkContinueResponse
        Text
"network.continueWithAuth" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
NetworkContinueWithAuth
        Text
"network.disownData" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
NetworkDisownData
        Text
"network.failRequest" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
NetworkFailRequest
        Text
"network.getData" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
NetworkGetData
        Text
"network.provideResponse" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
NetworkProvideResponse
        Text
"network.removeDataCollector" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
NetworkRemoveDataCollector
        Text
"network.removeIntercept" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
NetworkRemoveIntercept
        Text
"network.setCacheBehavior" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
NetworkSetCacheBehavior
        Text
"network.setExtraHeaders" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
NetworkSetExtraHeaders
        Text
"script.addPreloadScript" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
ScriptAddPreloadScript
        Text
"script.callFunction" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
ScriptCallFunction
        Text
"script.disown" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
ScriptDisown
        Text
"script.evaluate" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
ScriptEvaluate
        Text
"script.getRealms" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
ScriptGetRealms
        Text
"script.removePreloadScript" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
ScriptRemovePreloadScript
        Text
"session.end" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
SessionEnd
        Text
"session.new" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
SessionNew
        Text
"session.status" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
SessionStatus
        Text
"session.subscribe" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
SessionSubscribe
        Text
"session.unsubscribe" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
SessionUnsubscribe
        Text
"storage.deleteCookies" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
StorageDeleteCookies
        Text
"storage.getCookies" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
StorageGetCookies
        Text
"storage.setCookie" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
StorageSetCookie
        Text
"webExtension.install" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
WebExtensionInstall
        Text
"webExtension.uninstall" -> KnownCommand -> Parser KnownCommand
forall {a}. a -> Parser a
p KnownCommand
WebExtensionUninstall
        Text
u -> Text -> Parser KnownCommand
forall {m :: * -> *} {a}. MonadFail m => Text -> m a
failConversion Text
u
      Value
c -> Text -> Parser KnownCommand
forall {m :: * -> *} {a}. MonadFail m => Text -> m a
failConversion (Text -> Parser KnownCommand) -> Text -> Parser KnownCommand
forall a b. (a -> b) -> a -> b
$ Value -> Text
jsonToText Value
c
    where
      p :: a -> Parser a
p = a -> Parser a
forall {a}. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
      failConversion :: Text -> m a
failConversion Text
c =
        String -> m a
forall a. String -> m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> m a) -> (Text -> String) -> Text -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
unpack (Text -> m a) -> Text -> m a
forall a b. (a -> b) -> a -> b
$
          Text
"Unrecognised CommandMethodType: "
            Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
c
            Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" - "
            Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"Expected one of: "
            Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" "
            Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> (Text -> [Text] -> Text
T.intercalate Text
", " ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ KnownCommand -> Text
knownCommandToText (KnownCommand -> Text) -> [KnownCommand] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. (Enum a, Bounded a) => [a]
enumerate @KnownCommand)

-- | Converts a 'KnownCommand' to its corresponding method name text.
knownCommandToText :: KnownCommand -> Text
knownCommandToText :: KnownCommand -> Text
knownCommandToText = \case
  KnownCommand
BrowserClose -> Text
"browser.close"
  KnownCommand
BrowserCreateUserContext -> Text
"browser.createUserContext"
  KnownCommand
BrowserGetClientWindows -> Text
"browser.getClientWindows"
  KnownCommand
BrowserGetUserContexts -> Text
"browser.getUserContexts"
  KnownCommand
BrowserRemoveUserContext -> Text
"browser.removeUserContext"
  KnownCommand
BrowserSetClientWindowState -> Text
"browser.setClientWindowState"
  KnownCommand
BrowserSetDownloadBehavior -> Text
"browser.setDownloadBehavior"
  KnownCommand
BrowsingContextActivate -> Text
"browsingContext.activate"
  KnownCommand
BrowsingContextCaptureScreenshot -> Text
"browsingContext.captureScreenshot"
  KnownCommand
BrowsingContextClose -> Text
"browsingContext.close"
  KnownCommand
BrowsingContextCreate -> Text
"browsingContext.create"
  KnownCommand
BrowsingContextGetTree -> Text
"browsingContext.getTree"
  KnownCommand
BrowsingContextHandleUserPrompt -> Text
"browsingContext.handleUserPrompt"
  KnownCommand
BrowsingContextLocateNodes -> Text
"browsingContext.locateNodes"
  KnownCommand
BrowsingContextNavigate -> Text
"browsingContext.navigate"
  KnownCommand
BrowsingContextPrint -> Text
"browsingContext.print"
  KnownCommand
BrowsingContextReload -> Text
"browsingContext.reload"
  KnownCommand
BrowsingContextSetViewport -> Text
"browsingContext.setViewport"
  KnownCommand
BrowsingContextTraverseHistory -> Text
"browsingContext.traverseHistory"
  KnownCommand
EmulationSetForcedColorsModeThemeOverride -> Text
"emulation.setForcedColorsModeThemeOverride"
  KnownCommand
EmulationSetGeolocationOverride -> Text
"emulation.setGeolocationOverride"
  KnownCommand
EmulationSetLocaleOverride -> Text
"emulation.setLocaleOverride"
  KnownCommand
EmulationSetNetworkConditions -> Text
"emulation.setNetworkConditions"
  KnownCommand
EmulationSetScreenOrientationOverride -> Text
"emulation.setScreenOrientationOverride"
  KnownCommand
EmulationSetScreenSettingsOverride -> Text
"emulation.setScreenSettingsOverride"
  KnownCommand
EmulationSetScriptingEnabled -> Text
"emulation.setScriptingEnabled"
  KnownCommand
EmulationSetTimezoneOverride -> Text
"emulation.setTimezoneOverride"
  KnownCommand
EmulationSetTouchOverride -> Text
"emulation.setTouchOverride"
  KnownCommand
EmulationSetUserAgentOverride -> Text
"emulation.setUserAgentOverride"
  KnownCommand
InputPerformActions -> Text
"input.performActions"
  KnownCommand
InputReleaseActions -> Text
"input.releaseActions"
  KnownCommand
InputSetFiles -> Text
"input.setFiles"
  KnownCommand
NetworkAddDataCollector -> Text
"network.addDataCollector"
  KnownCommand
NetworkAddIntercept -> Text
"network.addIntercept"
  KnownCommand
NetworkContinueRequest -> Text
"network.continueRequest"
  KnownCommand
NetworkContinueResponse -> Text
"network.continueResponse"
  KnownCommand
NetworkContinueWithAuth -> Text
"network.continueWithAuth"
  KnownCommand
NetworkDisownData -> Text
"network.disownData"
  KnownCommand
NetworkFailRequest -> Text
"network.failRequest"
  KnownCommand
NetworkGetData -> Text
"network.getData"
  KnownCommand
NetworkProvideResponse -> Text
"network.provideResponse"
  KnownCommand
NetworkRemoveDataCollector -> Text
"network.removeDataCollector"
  KnownCommand
NetworkRemoveIntercept -> Text
"network.removeIntercept"
  KnownCommand
NetworkSetCacheBehavior -> Text
"network.setCacheBehavior"
  KnownCommand
NetworkSetExtraHeaders -> Text
"network.setExtraHeaders"
  KnownCommand
ScriptAddPreloadScript -> Text
"script.addPreloadScript"
  KnownCommand
ScriptCallFunction -> Text
"script.callFunction"
  KnownCommand
ScriptDisown -> Text
"script.disown"
  KnownCommand
ScriptEvaluate -> Text
"script.evaluate"
  KnownCommand
ScriptGetRealms -> Text
"script.getRealms"
  KnownCommand
ScriptRemovePreloadScript -> Text
"script.removePreloadScript"
  KnownCommand
SessionEnd -> Text
"session.end"
  KnownCommand
SessionNew -> Text
"session.new"
  KnownCommand
SessionStatus -> Text
"session.status"
  KnownCommand
SessionSubscribe -> Text
"session.subscribe"
  KnownCommand
SessionUnsubscribe -> Text
"session.unsubscribe"
  KnownCommand
StorageDeleteCookies -> Text
"storage.deleteCookies"
  KnownCommand
StorageGetCookies -> Text
"storage.getCookies"
  KnownCommand
StorageSetCookie -> Text
"storage.setCookie"
  KnownCommand
WebExtensionInstall -> Text
"webExtension.install"
  KnownCommand
WebExtensionUninstall -> Text
"webExtension.uninstall"

-- | Converts a 'CommandMethod' to its corresponding method name text.
toCommandText :: CommandMethod -> Text
toCommandText :: CommandMethod -> Text
toCommandText = \case
  KnownCommand KnownCommand
k -> KnownCommand -> Text
knownCommandToText KnownCommand
k
  OffSpecCommand (MkOffSpecCommand Text
t) -> Text
t

instance FromJSON CommandMethod where
  parseJSON :: Value -> Parser CommandMethod
  parseJSON :: Value -> Parser CommandMethod
parseJSON Value
val =
    (KnownCommand -> CommandMethod
KnownCommand (KnownCommand -> CommandMethod)
-> Parser KnownCommand -> Parser CommandMethod
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FromJSON a => Value -> Parser a
parseJSON @KnownCommand Value
val)
      Parser CommandMethod
-> Parser CommandMethod -> Parser CommandMethod
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (OffSpecCommand -> CommandMethod
OffSpecCommand (OffSpecCommand -> CommandMethod)
-> Parser OffSpecCommand -> Parser CommandMethod
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FromJSON a => Value -> Parser a
parseJSON @OffSpecCommand Value
val)
      Parser CommandMethod
-> Parser CommandMethod -> Parser CommandMethod
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser CommandMethod
failConversion
    where
      failConversion :: Parser CommandMethod
failConversion =
        String -> Parser CommandMethod
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser CommandMethod)
-> (Text -> String) -> Text -> Parser CommandMethod
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
unpack (Text -> Parser CommandMethod) -> Text -> Parser CommandMethod
forall a b. (a -> b) -> a -> b
$
          Text
"Unrecognised CommandMethodType: "
            Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Value -> Text
jsonToText Value
val
            Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" - "
            Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"Expected a string, the standard command types of whcih are: "
            Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" "
            Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> (Text -> [Text] -> Text
T.intercalate Text
", " ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ KnownCommand -> Text
knownCommandToText (KnownCommand -> Text) -> [KnownCommand] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. (Enum a, Bounded a) => [a]
enumerate @KnownCommand)