{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
# LANGUAGE ScopedTypeVariables #
# LANGUAGE FlexibleContexts #
# LANGUAGE MultiParamTypeClasses #
# LANGUAGE FlexibleInstances #
# LANGUAGE DeriveGeneric #
# LANGUAGE TypeFamilies #


{- |
= Fetch

A domain for letting clients substitute browser's network layer with client code.
-}


module CDP.Domains.Fetch (module CDP.Domains.Fetch) where

import           Control.Applicative  ((<$>))
import           Control.Monad
import           Control.Monad.Loops
import           Control.Monad.Trans  (liftIO)
import qualified Data.Map             as M
import           Data.Maybe          
import Data.Functor.Identity
import Data.String
import qualified Data.Text as T
import qualified Data.List as List
import qualified Data.Text.IO         as TI
import qualified Data.Vector          as V
import Data.Aeson.Types (Parser(..))
import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
import qualified Data.Aeson           as A
import qualified Network.HTTP.Simple as Http
import qualified Network.URI          as Uri
import qualified Network.WebSockets as WS
import Control.Concurrent
import qualified Data.ByteString.Lazy as BS
import qualified Data.Map as Map
import Data.Proxy
import System.Random
import GHC.Generics
import Data.Char
import Data.Default

import CDP.Internal.Utils


import CDP.Domains.DOMPageNetworkEmulationSecurity as DOMPageNetworkEmulationSecurity
import CDP.Domains.IO as IO


-- | Type 'Fetch.RequestId'.
--   Unique request identifier.
type FetchRequestId = T.Text

  | Type ' Fetch . RequestStage ' .
--   Stages of the request to handle. Request will intercept before the request is
--   sent. Response will intercept after the response is received (but before response
--   body is received).
data FetchRequestStage = FetchRequestStageRequest | FetchRequestStageResponse
  deriving (Ord, Eq, Show, Read)
instance FromJSON FetchRequestStage where
  parseJSON = A.withText "FetchRequestStage" $ \v -> case v of
    "Request" -> pure FetchRequestStageRequest
    "Response" -> pure FetchRequestStageResponse
    "_" -> fail "failed to parse FetchRequestStage"
instance ToJSON FetchRequestStage where
  toJSON v = A.String $ case v of
    FetchRequestStageRequest -> "Request"
    FetchRequestStageResponse -> "Response"

-- | Type 'Fetch.RequestPattern'.
data FetchRequestPattern = FetchRequestPattern
  {
  | Wildcards ( ` ' * ' ` - > zero or more , ` ' ? ' ` - > exactly one ) are allowed . Escape character is
    --   backslash. Omitting is equivalent to `"*"`.
    fetchRequestPatternUrlPattern :: Maybe T.Text,
    -- | If set, only requests for matching resource types will be intercepted.
    fetchRequestPatternResourceType :: Maybe DOMPageNetworkEmulationSecurity.NetworkResourceType,
    -- | Stage at which to begin intercepting requests. Default is Request.
    fetchRequestPatternRequestStage :: Maybe FetchRequestStage
  }
  deriving (Eq, Show)
instance FromJSON FetchRequestPattern where
  parseJSON = A.withObject "FetchRequestPattern" $ \o -> FetchRequestPattern
    <$> o A..:? "urlPattern"
    <*> o A..:? "resourceType"
    <*> o A..:? "requestStage"
instance ToJSON FetchRequestPattern where
  toJSON p = A.object $ catMaybes [
    ("urlPattern" A..=) <$> (fetchRequestPatternUrlPattern p),
    ("resourceType" A..=) <$> (fetchRequestPatternResourceType p),
    ("requestStage" A..=) <$> (fetchRequestPatternRequestStage p)
    ]

-- | Type 'Fetch.HeaderEntry'.
--   Response HTTP header entry
data FetchHeaderEntry = FetchHeaderEntry
  {
    fetchHeaderEntryName :: T.Text,
    fetchHeaderEntryValue :: T.Text
  }
  deriving (Eq, Show)
instance FromJSON FetchHeaderEntry where
  parseJSON = A.withObject "FetchHeaderEntry" $ \o -> FetchHeaderEntry
    <$> o A..: "name"
    <*> o A..: "value"
instance ToJSON FetchHeaderEntry where
  toJSON p = A.object $ catMaybes [
    ("name" A..=) <$> Just (fetchHeaderEntryName p),
    ("value" A..=) <$> Just (fetchHeaderEntryValue p)
    ]

-- | Type 'Fetch.AuthChallenge'.
    Authorization challenge for HTTP status code 401 or 407 .
data FetchAuthChallengeSource = FetchAuthChallengeSourceServer | FetchAuthChallengeSourceProxy
  deriving (Ord, Eq, Show, Read)
instance FromJSON FetchAuthChallengeSource where
  parseJSON = A.withText "FetchAuthChallengeSource" $ \v -> case v of
    "Server" -> pure FetchAuthChallengeSourceServer
    "Proxy" -> pure FetchAuthChallengeSourceProxy
    "_" -> fail "failed to parse FetchAuthChallengeSource"
instance ToJSON FetchAuthChallengeSource where
  toJSON v = A.String $ case v of
    FetchAuthChallengeSourceServer -> "Server"
    FetchAuthChallengeSourceProxy -> "Proxy"
data FetchAuthChallenge = FetchAuthChallenge
  {
    -- | Source of the authentication challenge.
    fetchAuthChallengeSource :: Maybe FetchAuthChallengeSource,
    -- | Origin of the challenger.
    fetchAuthChallengeOrigin :: T.Text,
    -- | The authentication scheme used, such as basic or digest
    fetchAuthChallengeScheme :: T.Text,
  | The realm of the challenge . May be empty .
    fetchAuthChallengeRealm :: T.Text
  }
  deriving (Eq, Show)
instance FromJSON FetchAuthChallenge where
  parseJSON = A.withObject "FetchAuthChallenge" $ \o -> FetchAuthChallenge
    <$> o A..:? "source"
    <*> o A..: "origin"
    <*> o A..: "scheme"
    <*> o A..: "realm"
instance ToJSON FetchAuthChallenge where
  toJSON p = A.object $ catMaybes [
    ("source" A..=) <$> (fetchAuthChallengeSource p),
    ("origin" A..=) <$> Just (fetchAuthChallengeOrigin p),
    ("scheme" A..=) <$> Just (fetchAuthChallengeScheme p),
    ("realm" A..=) <$> Just (fetchAuthChallengeRealm p)
    ]

-- | Type 'Fetch.AuthChallengeResponse'.
    Response to an AuthChallenge .
data FetchAuthChallengeResponseResponse = FetchAuthChallengeResponseResponseDefault | FetchAuthChallengeResponseResponseCancelAuth | FetchAuthChallengeResponseResponseProvideCredentials
  deriving (Ord, Eq, Show, Read)
instance FromJSON FetchAuthChallengeResponseResponse where
  parseJSON = A.withText "FetchAuthChallengeResponseResponse" $ \v -> case v of
    "Default" -> pure FetchAuthChallengeResponseResponseDefault
    "CancelAuth" -> pure FetchAuthChallengeResponseResponseCancelAuth
    "ProvideCredentials" -> pure FetchAuthChallengeResponseResponseProvideCredentials
    "_" -> fail "failed to parse FetchAuthChallengeResponseResponse"
instance ToJSON FetchAuthChallengeResponseResponse where
  toJSON v = A.String $ case v of
    FetchAuthChallengeResponseResponseDefault -> "Default"
    FetchAuthChallengeResponseResponseCancelAuth -> "CancelAuth"
    FetchAuthChallengeResponseResponseProvideCredentials -> "ProvideCredentials"
data FetchAuthChallengeResponse = FetchAuthChallengeResponse
  {
    -- | The decision on what to do in response to the authorization challenge.  Default means
    deferring to the default behavior of the net stack , which will likely either the Cancel
    --   authentication or display a popup dialog box.
    fetchAuthChallengeResponseResponse :: FetchAuthChallengeResponseResponse,
    -- | The username to provide, possibly empty. Should only be set if response is
    ProvideCredentials .
    fetchAuthChallengeResponseUsername :: Maybe T.Text,
    -- | The password to provide, possibly empty. Should only be set if response is
    ProvideCredentials .
    fetchAuthChallengeResponsePassword :: Maybe T.Text
  }
  deriving (Eq, Show)
instance FromJSON FetchAuthChallengeResponse where
  parseJSON = A.withObject "FetchAuthChallengeResponse" $ \o -> FetchAuthChallengeResponse
    <$> o A..: "response"
    <*> o A..:? "username"
    <*> o A..:? "password"
instance ToJSON FetchAuthChallengeResponse where
  toJSON p = A.object $ catMaybes [
    ("response" A..=) <$> Just (fetchAuthChallengeResponseResponse p),
    ("username" A..=) <$> (fetchAuthChallengeResponseUsername p),
    ("password" A..=) <$> (fetchAuthChallengeResponsePassword p)
    ]

-- | Type of the 'Fetch.requestPaused' event.
data FetchRequestPaused = FetchRequestPaused
  {
    -- | Each request the page makes will have a unique id.
    fetchRequestPausedRequestId :: FetchRequestId,
    -- | The details of the request.
    fetchRequestPausedRequest :: DOMPageNetworkEmulationSecurity.NetworkRequest,
    -- | The id of the frame that initiated the request.
    fetchRequestPausedFrameId :: DOMPageNetworkEmulationSecurity.PageFrameId,
    -- | How the requested resource will be used.
    fetchRequestPausedResourceType :: DOMPageNetworkEmulationSecurity.NetworkResourceType,
    -- | Response error if intercepted at response stage.
    fetchRequestPausedResponseErrorReason :: Maybe DOMPageNetworkEmulationSecurity.NetworkErrorReason,
    -- | Response code if intercepted at response stage.
    fetchRequestPausedResponseStatusCode :: Maybe Int,
    -- | Response status text if intercepted at response stage.
    fetchRequestPausedResponseStatusText :: Maybe T.Text,
    -- | Response headers if intercepted at the response stage.
    fetchRequestPausedResponseHeaders :: Maybe [FetchHeaderEntry],
    -- | If the intercepted request had a corresponding Network.requestWillBeSent event fired for it,
    then this networkId will be the same as the requestId present in the requestWillBeSent event .
    fetchRequestPausedNetworkId :: Maybe DOMPageNetworkEmulationSecurity.NetworkRequestId,
    -- | If the request is due to a redirect response from the server, the id of the request that
    --   has caused the redirect.
    fetchRequestPausedRedirectedRequestId :: Maybe FetchRequestId
  }
  deriving (Eq, Show)
instance FromJSON FetchRequestPaused where
  parseJSON = A.withObject "FetchRequestPaused" $ \o -> FetchRequestPaused
    <$> o A..: "requestId"
    <*> o A..: "request"
    <*> o A..: "frameId"
    <*> o A..: "resourceType"
    <*> o A..:? "responseErrorReason"
    <*> o A..:? "responseStatusCode"
    <*> o A..:? "responseStatusText"
    <*> o A..:? "responseHeaders"
    <*> o A..:? "networkId"
    <*> o A..:? "redirectedRequestId"
instance Event FetchRequestPaused where
  eventName _ = "Fetch.requestPaused"

-- | Type of the 'Fetch.authRequired' event.
data FetchAuthRequired = FetchAuthRequired
  {
    -- | Each request the page makes will have a unique id.
    fetchAuthRequiredRequestId :: FetchRequestId,
    -- | The details of the request.
    fetchAuthRequiredRequest :: DOMPageNetworkEmulationSecurity.NetworkRequest,
    -- | The id of the frame that initiated the request.
    fetchAuthRequiredFrameId :: DOMPageNetworkEmulationSecurity.PageFrameId,
    -- | How the requested resource will be used.
    fetchAuthRequiredResourceType :: DOMPageNetworkEmulationSecurity.NetworkResourceType,
  | Details of the Authorization Challenge encountered .
    If this is set , client should respond with  that
    --   contains AuthChallengeResponse.
    fetchAuthRequiredAuthChallenge :: FetchAuthChallenge
  }
  deriving (Eq, Show)
instance FromJSON FetchAuthRequired where
  parseJSON = A.withObject "FetchAuthRequired" $ \o -> FetchAuthRequired
    <$> o A..: "requestId"
    <*> o A..: "request"
    <*> o A..: "frameId"
    <*> o A..: "resourceType"
    <*> o A..: "authChallenge"
instance Event FetchAuthRequired where
  eventName _ = "Fetch.authRequired"

-- | Disables the fetch domain.

-- | Parameters of the 'Fetch.disable' command.
data PFetchDisable = PFetchDisable
  deriving (Eq, Show)
pFetchDisable
  :: PFetchDisable
pFetchDisable
  = PFetchDisable
instance ToJSON PFetchDisable where
  toJSON _ = A.Null
instance Command PFetchDisable where
  type CommandResponse PFetchDisable = ()
  commandName _ = "Fetch.disable"
  fromJSON = const . A.Success . const ()

-- | Enables issuing of requestPaused events. A request will be paused until client
    calls one of failRequest , fulfillRequest or  / continueWithAuth .

-- | Parameters of the 'Fetch.enable' command.
data PFetchEnable = PFetchEnable
  {
    -- | If specified, only requests matching any of these patterns will produce
    --   fetchRequested event and will be paused until clients response. If not set,
    --   all requests will be affected.
    pFetchEnablePatterns :: Maybe [FetchRequestPattern],
    -- | If true, authRequired events will be issued and requests will be paused
    --   expecting a call to continueWithAuth.
    pFetchEnableHandleAuthRequests :: Maybe Bool
  }
  deriving (Eq, Show)
pFetchEnable
  :: PFetchEnable
pFetchEnable
  = PFetchEnable
    Nothing
    Nothing
instance ToJSON PFetchEnable where
  toJSON p = A.object $ catMaybes [
    ("patterns" A..=) <$> (pFetchEnablePatterns p),
    ("handleAuthRequests" A..=) <$> (pFetchEnableHandleAuthRequests p)
    ]
instance Command PFetchEnable where
  type CommandResponse PFetchEnable = ()
  commandName _ = "Fetch.enable"
  fromJSON = const . A.Success . const ()

-- | Causes the request to fail with specified reason.

-- | Parameters of the 'Fetch.failRequest' command.
data PFetchFailRequest = PFetchFailRequest
  {
    -- | An id the client received in requestPaused event.
    pFetchFailRequestRequestId :: FetchRequestId,
    -- | Causes the request to fail with the given reason.
    pFetchFailRequestErrorReason :: DOMPageNetworkEmulationSecurity.NetworkErrorReason
  }
  deriving (Eq, Show)
pFetchFailRequest
  {-
  -- | An id the client received in requestPaused event.
  -}
  :: FetchRequestId
  {-
  -- | Causes the request to fail with the given reason.
  -}
  -> DOMPageNetworkEmulationSecurity.NetworkErrorReason
  -> PFetchFailRequest
pFetchFailRequest
  arg_pFetchFailRequestRequestId
  arg_pFetchFailRequestErrorReason
  = PFetchFailRequest
    arg_pFetchFailRequestRequestId
    arg_pFetchFailRequestErrorReason
instance ToJSON PFetchFailRequest where
  toJSON p = A.object $ catMaybes [
    ("requestId" A..=) <$> Just (pFetchFailRequestRequestId p),
    ("errorReason" A..=) <$> Just (pFetchFailRequestErrorReason p)
    ]
instance Command PFetchFailRequest where
  type CommandResponse PFetchFailRequest = ()
  commandName _ = "Fetch.failRequest"
  fromJSON = const . A.Success . const ()

-- | Provides response to the request.

-- | Parameters of the 'Fetch.fulfillRequest' command.
data PFetchFulfillRequest = PFetchFulfillRequest
  {
    -- | An id the client received in requestPaused event.
    pFetchFulfillRequestRequestId :: FetchRequestId,
    -- | An HTTP response code.
    pFetchFulfillRequestResponseCode :: Int,
    -- | Response headers.
    pFetchFulfillRequestResponseHeaders :: Maybe [FetchHeaderEntry],
    -- | Alternative way of specifying response headers as a \0-separated
    --   series of name: value pairs. Prefer the above method unless you
    --   need to represent some non-UTF8 values that can't be transmitted
    --   over the protocol as text. (Encoded as a base64 string when passed over JSON)
    pFetchFulfillRequestBinaryResponseHeaders :: Maybe T.Text,
    -- | A response body. If absent, original response body will be used if
    --   the request is intercepted at the response stage and empty body
    --   will be used if the request is intercepted at the request stage. (Encoded as a base64 string when passed over JSON)
    pFetchFulfillRequestBody :: Maybe T.Text,
    -- | A textual representation of responseCode.
    --   If absent, a standard phrase matching responseCode is used.
    pFetchFulfillRequestResponsePhrase :: Maybe T.Text
  }
  deriving (Eq, Show)
pFetchFulfillRequest
  {-
  -- | An id the client received in requestPaused event.
  -}
  :: FetchRequestId
  {-
  -- | An HTTP response code.
  -}
  -> Int
  -> PFetchFulfillRequest
pFetchFulfillRequest
  arg_pFetchFulfillRequestRequestId
  arg_pFetchFulfillRequestResponseCode
  = PFetchFulfillRequest
    arg_pFetchFulfillRequestRequestId
    arg_pFetchFulfillRequestResponseCode
    Nothing
    Nothing
    Nothing
    Nothing
instance ToJSON PFetchFulfillRequest where
  toJSON p = A.object $ catMaybes [
    ("requestId" A..=) <$> Just (pFetchFulfillRequestRequestId p),
    ("responseCode" A..=) <$> Just (pFetchFulfillRequestResponseCode p),
    ("responseHeaders" A..=) <$> (pFetchFulfillRequestResponseHeaders p),
    ("binaryResponseHeaders" A..=) <$> (pFetchFulfillRequestBinaryResponseHeaders p),
    ("body" A..=) <$> (pFetchFulfillRequestBody p),
    ("responsePhrase" A..=) <$> (pFetchFulfillRequestResponsePhrase p)
    ]
instance Command PFetchFulfillRequest where
  type CommandResponse PFetchFulfillRequest = ()
  commandName _ = "Fetch.fulfillRequest"
  fromJSON = const . A.Success . const ()

-- | Continues the request, optionally modifying some of its parameters.

-- | Parameters of the 'Fetch.continueRequest' command.
data PFetchContinueRequest = PFetchContinueRequest
  {
    -- | An id the client received in requestPaused event.
    pFetchContinueRequestRequestId :: FetchRequestId,
    -- | If set, the request url will be modified in a way that's not observable by page.
    pFetchContinueRequestUrl :: Maybe T.Text,
    -- | If set, the request method is overridden.
    pFetchContinueRequestMethod :: Maybe T.Text,
    -- | If set, overrides the post data in the request. (Encoded as a base64 string when passed over JSON)
    pFetchContinueRequestPostData :: Maybe T.Text,
    -- | If set, overrides the request headers. Note that the overrides do not
    --   extend to subsequent redirect hops, if a redirect happens. Another override
    --   may be applied to a different request produced by a redirect.
    pFetchContinueRequestHeaders :: Maybe [FetchHeaderEntry],
    -- | If set, overrides response interception behavior for this request.
    pFetchContinueRequestInterceptResponse :: Maybe Bool
  }
  deriving (Eq, Show)
pFetchContinueRequest
  {-
  -- | An id the client received in requestPaused event.
  -}
  :: FetchRequestId
  -> PFetchContinueRequest
pFetchContinueRequest
  arg_pFetchContinueRequestRequestId
  = PFetchContinueRequest
    arg_pFetchContinueRequestRequestId
    Nothing
    Nothing
    Nothing
    Nothing
    Nothing
instance ToJSON PFetchContinueRequest where
  toJSON p = A.object $ catMaybes [
    ("requestId" A..=) <$> Just (pFetchContinueRequestRequestId p),
    ("url" A..=) <$> (pFetchContinueRequestUrl p),
    ("method" A..=) <$> (pFetchContinueRequestMethod p),
    ("postData" A..=) <$> (pFetchContinueRequestPostData p),
    ("headers" A..=) <$> (pFetchContinueRequestHeaders p),
    ("interceptResponse" A..=) <$> (pFetchContinueRequestInterceptResponse p)
    ]
instance Command PFetchContinueRequest where
  type CommandResponse PFetchContinueRequest = ()
  commandName _ = "Fetch.continueRequest"
  fromJSON = const . A.Success . const ()

-- | Continues a request supplying authChallengeResponse following authRequired event.

  | Parameters of the ' Fetch.continueWithAuth ' command .
data PFetchContinueWithAuth = PFetchContinueWithAuth
  {
    -- | An id the client received in authRequired event.
    pFetchContinueWithAuthRequestId :: FetchRequestId,
    -- | Response to  with an authChallenge.
    pFetchContinueWithAuthAuthChallengeResponse :: FetchAuthChallengeResponse
  }
  deriving (Eq, Show)
pFetchContinueWithAuth
  {-
  -- | An id the client received in authRequired event.
  -}
  :: FetchRequestId
  {-
  -- | Response to  with an authChallenge.
  -}
  -> FetchAuthChallengeResponse
  -> PFetchContinueWithAuth
pFetchContinueWithAuth
  arg_pFetchContinueWithAuthRequestId
  arg_pFetchContinueWithAuthAuthChallengeResponse
  = PFetchContinueWithAuth
    arg_pFetchContinueWithAuthRequestId
    arg_pFetchContinueWithAuthAuthChallengeResponse
instance ToJSON PFetchContinueWithAuth where
  toJSON p = A.object $ catMaybes [
    ("requestId" A..=) <$> Just (pFetchContinueWithAuthRequestId p),
    ("authChallengeResponse" A..=) <$> Just (pFetchContinueWithAuthAuthChallengeResponse p)
    ]
instance Command PFetchContinueWithAuth where
  type CommandResponse PFetchContinueWithAuth = ()
  commandName _ = "Fetch.continueWithAuth"
  fromJSON = const . A.Success . const ()

-- | Continues loading of the paused response, optionally modifying the
--   response headers. If either responseCode or headers are modified, all of them
--   must be present.

-- | Parameters of the 'Fetch.continueResponse' command.
data PFetchContinueResponse = PFetchContinueResponse
  {
    -- | An id the client received in requestPaused event.
    pFetchContinueResponseRequestId :: FetchRequestId,
    -- | An HTTP response code. If absent, original response code will be used.
    pFetchContinueResponseResponseCode :: Maybe Int,
    -- | A textual representation of responseCode.
    --   If absent, a standard phrase matching responseCode is used.
    pFetchContinueResponseResponsePhrase :: Maybe T.Text,
    -- | Response headers. If absent, original response headers will be used.
    pFetchContinueResponseResponseHeaders :: Maybe [FetchHeaderEntry],
    -- | Alternative way of specifying response headers as a \0-separated
    --   series of name: value pairs. Prefer the above method unless you
    --   need to represent some non-UTF8 values that can't be transmitted
    --   over the protocol as text. (Encoded as a base64 string when passed over JSON)
    pFetchContinueResponseBinaryResponseHeaders :: Maybe T.Text
  }
  deriving (Eq, Show)
pFetchContinueResponse
  {-
  -- | An id the client received in requestPaused event.
  -}
  :: FetchRequestId
  -> PFetchContinueResponse
pFetchContinueResponse
  arg_pFetchContinueResponseRequestId
  = PFetchContinueResponse
    arg_pFetchContinueResponseRequestId
    Nothing
    Nothing
    Nothing
    Nothing
instance ToJSON PFetchContinueResponse where
  toJSON p = A.object $ catMaybes [
    ("requestId" A..=) <$> Just (pFetchContinueResponseRequestId p),
    ("responseCode" A..=) <$> (pFetchContinueResponseResponseCode p),
    ("responsePhrase" A..=) <$> (pFetchContinueResponseResponsePhrase p),
    ("responseHeaders" A..=) <$> (pFetchContinueResponseResponseHeaders p),
    ("binaryResponseHeaders" A..=) <$> (pFetchContinueResponseBinaryResponseHeaders p)
    ]
instance Command PFetchContinueResponse where
  type CommandResponse PFetchContinueResponse = ()
  commandName _ = "Fetch.continueResponse"
  fromJSON = const . A.Success . const ()

-- | Causes the body of the response to be received from the server and
    returned as a single string . May only be issued for a request that
--   is paused in the Response stage and is mutually exclusive with
--   takeResponseBodyForInterceptionAsStream. Calling other methods that
--   affect the request or disabling fetch domain before body is received
--   results in an undefined behavior.

-- | Parameters of the 'Fetch.getResponseBody' command.
data PFetchGetResponseBody = PFetchGetResponseBody
  {
    -- | Identifier for the intercepted request to get body for.
    pFetchGetResponseBodyRequestId :: FetchRequestId
  }
  deriving (Eq, Show)
pFetchGetResponseBody
  {-
  -- | Identifier for the intercepted request to get body for.
  -}
  :: FetchRequestId
  -> PFetchGetResponseBody
pFetchGetResponseBody
  arg_pFetchGetResponseBodyRequestId
  = PFetchGetResponseBody
    arg_pFetchGetResponseBodyRequestId
instance ToJSON PFetchGetResponseBody where
  toJSON p = A.object $ catMaybes [
    ("requestId" A..=) <$> Just (pFetchGetResponseBodyRequestId p)
    ]
data FetchGetResponseBody = FetchGetResponseBody
  {
    -- | Response body.
    fetchGetResponseBodyBody :: T.Text,
    -- | True, if content was sent as base64.
    fetchGetResponseBodyBase64Encoded :: Bool
  }
  deriving (Eq, Show)
instance FromJSON FetchGetResponseBody where
  parseJSON = A.withObject "FetchGetResponseBody" $ \o -> FetchGetResponseBody
    <$> o A..: "body"
    <*> o A..: "base64Encoded"
instance Command PFetchGetResponseBody where
  type CommandResponse PFetchGetResponseBody = FetchGetResponseBody
  commandName _ = "Fetch.getResponseBody"

-- | Returns a handle to the stream representing the response body.
--   The request must be paused in the HeadersReceived stage.
--   Note that after this command the request can't be continued
--   as is -- client either needs to cancel it or to provide the
--   response body.
    The stream only supports sequential read ,  will fail if the position
--   is specified.
--   This method is mutually exclusive with getResponseBody.
--   Calling other methods that affect the request or disabling fetch
--   domain before body is received results in an undefined behavior.

-- | Parameters of the 'Fetch.takeResponseBodyAsStream' command.
data PFetchTakeResponseBodyAsStream = PFetchTakeResponseBodyAsStream
  {
    pFetchTakeResponseBodyAsStreamRequestId :: FetchRequestId
  }
  deriving (Eq, Show)
pFetchTakeResponseBodyAsStream
  :: FetchRequestId
  -> PFetchTakeResponseBodyAsStream
pFetchTakeResponseBodyAsStream
  arg_pFetchTakeResponseBodyAsStreamRequestId
  = PFetchTakeResponseBodyAsStream
    arg_pFetchTakeResponseBodyAsStreamRequestId
instance ToJSON PFetchTakeResponseBodyAsStream where
  toJSON p = A.object $ catMaybes [
    ("requestId" A..=) <$> Just (pFetchTakeResponseBodyAsStreamRequestId p)
    ]
data FetchTakeResponseBodyAsStream = FetchTakeResponseBodyAsStream
  {
    fetchTakeResponseBodyAsStreamStream :: IO.IOStreamHandle
  }
  deriving (Eq, Show)
instance FromJSON FetchTakeResponseBodyAsStream where
  parseJSON = A.withObject "FetchTakeResponseBodyAsStream" $ \o -> FetchTakeResponseBodyAsStream
    <$> o A..: "stream"
instance Command PFetchTakeResponseBodyAsStream where
  type CommandResponse PFetchTakeResponseBodyAsStream = FetchTakeResponseBodyAsStream
  commandName _ = "Fetch.takeResponseBodyAsStream"


# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #
 |
= Fetch

A domain for letting clients substitute browser's network layer with client code.

 | Type 'Fetch.RequestId'.
   Unique request identifier.
   Stages of the request to handle. Request will intercept before the request is
   sent. Response will intercept after the response is received (but before response
   body is received).
 | Type 'Fetch.RequestPattern'.
   backslash. Omitting is equivalent to `"*"`.
 | If set, only requests for matching resource types will be intercepted.
 | Stage at which to begin intercepting requests. Default is Request.
 | Type 'Fetch.HeaderEntry'.
   Response HTTP header entry
 | Type 'Fetch.AuthChallenge'.
 | Source of the authentication challenge.
 | Origin of the challenger.
 | The authentication scheme used, such as basic or digest
 | Type 'Fetch.AuthChallengeResponse'.
 | The decision on what to do in response to the authorization challenge.  Default means
   authentication or display a popup dialog box.
 | The username to provide, possibly empty. Should only be set if response is
 | The password to provide, possibly empty. Should only be set if response is
 | Type of the 'Fetch.requestPaused' event.
 | Each request the page makes will have a unique id.
 | The details of the request.
 | The id of the frame that initiated the request.
 | How the requested resource will be used.
 | Response error if intercepted at response stage.
 | Response code if intercepted at response stage.
 | Response status text if intercepted at response stage.
 | Response headers if intercepted at the response stage.
 | If the intercepted request had a corresponding Network.requestWillBeSent event fired for it,
 | If the request is due to a redirect response from the server, the id of the request that
   has caused the redirect.
 | Type of the 'Fetch.authRequired' event.
 | Each request the page makes will have a unique id.
 | The details of the request.
 | The id of the frame that initiated the request.
 | How the requested resource will be used.
   contains AuthChallengeResponse.
 | Disables the fetch domain.
 | Parameters of the 'Fetch.disable' command.
 | Enables issuing of requestPaused events. A request will be paused until client
 | Parameters of the 'Fetch.enable' command.
 | If specified, only requests matching any of these patterns will produce
   fetchRequested event and will be paused until clients response. If not set,
   all requests will be affected.
 | If true, authRequired events will be issued and requests will be paused
   expecting a call to continueWithAuth.
 | Causes the request to fail with specified reason.
 | Parameters of the 'Fetch.failRequest' command.
 | An id the client received in requestPaused event.
 | Causes the request to fail with the given reason.

  -- | An id the client received in requestPaused event.
  

  -- | Causes the request to fail with the given reason.
  
 | Provides response to the request.
 | Parameters of the 'Fetch.fulfillRequest' command.
 | An id the client received in requestPaused event.
 | An HTTP response code.
 | Response headers.
 | Alternative way of specifying response headers as a \0-separated
   series of name: value pairs. Prefer the above method unless you
   need to represent some non-UTF8 values that can't be transmitted
   over the protocol as text. (Encoded as a base64 string when passed over JSON)
 | A response body. If absent, original response body will be used if
   the request is intercepted at the response stage and empty body
   will be used if the request is intercepted at the request stage. (Encoded as a base64 string when passed over JSON)
 | A textual representation of responseCode.
   If absent, a standard phrase matching responseCode is used.

  -- | An id the client received in requestPaused event.
  

  -- | An HTTP response code.
  
 | Continues the request, optionally modifying some of its parameters.
 | Parameters of the 'Fetch.continueRequest' command.
 | An id the client received in requestPaused event.
 | If set, the request url will be modified in a way that's not observable by page.
 | If set, the request method is overridden.
 | If set, overrides the post data in the request. (Encoded as a base64 string when passed over JSON)
 | If set, overrides the request headers. Note that the overrides do not
   extend to subsequent redirect hops, if a redirect happens. Another override
   may be applied to a different request produced by a redirect.
 | If set, overrides response interception behavior for this request.

  -- | An id the client received in requestPaused event.
  
 | Continues a request supplying authChallengeResponse following authRequired event.
 | An id the client received in authRequired event.
 | Response to  with an authChallenge.

  -- | An id the client received in authRequired event.
  

  -- | Response to  with an authChallenge.
  
 | Continues loading of the paused response, optionally modifying the
   response headers. If either responseCode or headers are modified, all of them
   must be present.
 | Parameters of the 'Fetch.continueResponse' command.
 | An id the client received in requestPaused event.
 | An HTTP response code. If absent, original response code will be used.
 | A textual representation of responseCode.
   If absent, a standard phrase matching responseCode is used.
 | Response headers. If absent, original response headers will be used.
 | Alternative way of specifying response headers as a \0-separated
   series of name: value pairs. Prefer the above method unless you
   need to represent some non-UTF8 values that can't be transmitted
   over the protocol as text. (Encoded as a base64 string when passed over JSON)

  -- | An id the client received in requestPaused event.
  
 | Causes the body of the response to be received from the server and
   is paused in the Response stage and is mutually exclusive with
   takeResponseBodyForInterceptionAsStream. Calling other methods that
   affect the request or disabling fetch domain before body is received
   results in an undefined behavior.
 | Parameters of the 'Fetch.getResponseBody' command.
 | Identifier for the intercepted request to get body for.

  -- | Identifier for the intercepted request to get body for.
  
 | Response body.
 | True, if content was sent as base64.
 | Returns a handle to the stream representing the response body.
   The request must be paused in the HeadersReceived stage.
   Note that after this command the request can't be continued
   as is -- client either needs to cancel it or to provide the
   response body.
   is specified.
   This method is mutually exclusive with getResponseBody.
   Calling other methods that affect the request or disabling fetch
   domain before body is received results in an undefined behavior.
 | Parameters of the 'Fetch.takeResponseBodyAsStream' command.
# LANGUAGE ScopedTypeVariables #
# LANGUAGE FlexibleContexts #
# LANGUAGE MultiParamTypeClasses #
# LANGUAGE FlexibleInstances #
# LANGUAGE DeriveGeneric #
# LANGUAGE TypeFamilies #




module CDP.Domains.Fetch (module CDP.Domains.Fetch) where

import           Control.Applicative  ((<$>))
import           Control.Monad
import           Control.Monad.Loops
import           Control.Monad.Trans  (liftIO)
import qualified Data.Map             as M
import           Data.Maybe          
import Data.Functor.Identity
import Data.String
import qualified Data.Text as T
import qualified Data.List as List
import qualified Data.Text.IO         as TI
import qualified Data.Vector          as V
import Data.Aeson.Types (Parser(..))
import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
import qualified Data.Aeson           as A
import qualified Network.HTTP.Simple as Http
import qualified Network.URI          as Uri
import qualified Network.WebSockets as WS
import Control.Concurrent
import qualified Data.ByteString.Lazy as BS
import qualified Data.Map as Map
import Data.Proxy
import System.Random
import GHC.Generics
import Data.Char
import Data.Default

import CDP.Internal.Utils


import CDP.Domains.DOMPageNetworkEmulationSecurity as DOMPageNetworkEmulationSecurity
import CDP.Domains.IO as IO


type FetchRequestId = T.Text

  | Type ' Fetch . RequestStage ' .
data FetchRequestStage = FetchRequestStageRequest | FetchRequestStageResponse
  deriving (Ord, Eq, Show, Read)
instance FromJSON FetchRequestStage where
  parseJSON = A.withText "FetchRequestStage" $ \v -> case v of
    "Request" -> pure FetchRequestStageRequest
    "Response" -> pure FetchRequestStageResponse
    "_" -> fail "failed to parse FetchRequestStage"
instance ToJSON FetchRequestStage where
  toJSON v = A.String $ case v of
    FetchRequestStageRequest -> "Request"
    FetchRequestStageResponse -> "Response"

data FetchRequestPattern = FetchRequestPattern
  {
  | Wildcards ( ` ' * ' ` - > zero or more , ` ' ? ' ` - > exactly one ) are allowed . Escape character is
    fetchRequestPatternUrlPattern :: Maybe T.Text,
    fetchRequestPatternResourceType :: Maybe DOMPageNetworkEmulationSecurity.NetworkResourceType,
    fetchRequestPatternRequestStage :: Maybe FetchRequestStage
  }
  deriving (Eq, Show)
instance FromJSON FetchRequestPattern where
  parseJSON = A.withObject "FetchRequestPattern" $ \o -> FetchRequestPattern
    <$> o A..:? "urlPattern"
    <*> o A..:? "resourceType"
    <*> o A..:? "requestStage"
instance ToJSON FetchRequestPattern where
  toJSON p = A.object $ catMaybes [
    ("urlPattern" A..=) <$> (fetchRequestPatternUrlPattern p),
    ("resourceType" A..=) <$> (fetchRequestPatternResourceType p),
    ("requestStage" A..=) <$> (fetchRequestPatternRequestStage p)
    ]

data FetchHeaderEntry = FetchHeaderEntry
  {
    fetchHeaderEntryName :: T.Text,
    fetchHeaderEntryValue :: T.Text
  }
  deriving (Eq, Show)
instance FromJSON FetchHeaderEntry where
  parseJSON = A.withObject "FetchHeaderEntry" $ \o -> FetchHeaderEntry
    <$> o A..: "name"
    <*> o A..: "value"
instance ToJSON FetchHeaderEntry where
  toJSON p = A.object $ catMaybes [
    ("name" A..=) <$> Just (fetchHeaderEntryName p),
    ("value" A..=) <$> Just (fetchHeaderEntryValue p)
    ]

    Authorization challenge for HTTP status code 401 or 407 .
data FetchAuthChallengeSource = FetchAuthChallengeSourceServer | FetchAuthChallengeSourceProxy
  deriving (Ord, Eq, Show, Read)
instance FromJSON FetchAuthChallengeSource where
  parseJSON = A.withText "FetchAuthChallengeSource" $ \v -> case v of
    "Server" -> pure FetchAuthChallengeSourceServer
    "Proxy" -> pure FetchAuthChallengeSourceProxy
    "_" -> fail "failed to parse FetchAuthChallengeSource"
instance ToJSON FetchAuthChallengeSource where
  toJSON v = A.String $ case v of
    FetchAuthChallengeSourceServer -> "Server"
    FetchAuthChallengeSourceProxy -> "Proxy"
data FetchAuthChallenge = FetchAuthChallenge
  {
    fetchAuthChallengeSource :: Maybe FetchAuthChallengeSource,
    fetchAuthChallengeOrigin :: T.Text,
    fetchAuthChallengeScheme :: T.Text,
  | The realm of the challenge . May be empty .
    fetchAuthChallengeRealm :: T.Text
  }
  deriving (Eq, Show)
instance FromJSON FetchAuthChallenge where
  parseJSON = A.withObject "FetchAuthChallenge" $ \o -> FetchAuthChallenge
    <$> o A..:? "source"
    <*> o A..: "origin"
    <*> o A..: "scheme"
    <*> o A..: "realm"
instance ToJSON FetchAuthChallenge where
  toJSON p = A.object $ catMaybes [
    ("source" A..=) <$> (fetchAuthChallengeSource p),
    ("origin" A..=) <$> Just (fetchAuthChallengeOrigin p),
    ("scheme" A..=) <$> Just (fetchAuthChallengeScheme p),
    ("realm" A..=) <$> Just (fetchAuthChallengeRealm p)
    ]

    Response to an AuthChallenge .
data FetchAuthChallengeResponseResponse = FetchAuthChallengeResponseResponseDefault | FetchAuthChallengeResponseResponseCancelAuth | FetchAuthChallengeResponseResponseProvideCredentials
  deriving (Ord, Eq, Show, Read)
instance FromJSON FetchAuthChallengeResponseResponse where
  parseJSON = A.withText "FetchAuthChallengeResponseResponse" $ \v -> case v of
    "Default" -> pure FetchAuthChallengeResponseResponseDefault
    "CancelAuth" -> pure FetchAuthChallengeResponseResponseCancelAuth
    "ProvideCredentials" -> pure FetchAuthChallengeResponseResponseProvideCredentials
    "_" -> fail "failed to parse FetchAuthChallengeResponseResponse"
instance ToJSON FetchAuthChallengeResponseResponse where
  toJSON v = A.String $ case v of
    FetchAuthChallengeResponseResponseDefault -> "Default"
    FetchAuthChallengeResponseResponseCancelAuth -> "CancelAuth"
    FetchAuthChallengeResponseResponseProvideCredentials -> "ProvideCredentials"
data FetchAuthChallengeResponse = FetchAuthChallengeResponse
  {
    deferring to the default behavior of the net stack , which will likely either the Cancel
    fetchAuthChallengeResponseResponse :: FetchAuthChallengeResponseResponse,
    ProvideCredentials .
    fetchAuthChallengeResponseUsername :: Maybe T.Text,
    ProvideCredentials .
    fetchAuthChallengeResponsePassword :: Maybe T.Text
  }
  deriving (Eq, Show)
instance FromJSON FetchAuthChallengeResponse where
  parseJSON = A.withObject "FetchAuthChallengeResponse" $ \o -> FetchAuthChallengeResponse
    <$> o A..: "response"
    <*> o A..:? "username"
    <*> o A..:? "password"
instance ToJSON FetchAuthChallengeResponse where
  toJSON p = A.object $ catMaybes [
    ("response" A..=) <$> Just (fetchAuthChallengeResponseResponse p),
    ("username" A..=) <$> (fetchAuthChallengeResponseUsername p),
    ("password" A..=) <$> (fetchAuthChallengeResponsePassword p)
    ]

data FetchRequestPaused = FetchRequestPaused
  {
    fetchRequestPausedRequestId :: FetchRequestId,
    fetchRequestPausedRequest :: DOMPageNetworkEmulationSecurity.NetworkRequest,
    fetchRequestPausedFrameId :: DOMPageNetworkEmulationSecurity.PageFrameId,
    fetchRequestPausedResourceType :: DOMPageNetworkEmulationSecurity.NetworkResourceType,
    fetchRequestPausedResponseErrorReason :: Maybe DOMPageNetworkEmulationSecurity.NetworkErrorReason,
    fetchRequestPausedResponseStatusCode :: Maybe Int,
    fetchRequestPausedResponseStatusText :: Maybe T.Text,
    fetchRequestPausedResponseHeaders :: Maybe [FetchHeaderEntry],
    then this networkId will be the same as the requestId present in the requestWillBeSent event .
    fetchRequestPausedNetworkId :: Maybe DOMPageNetworkEmulationSecurity.NetworkRequestId,
    fetchRequestPausedRedirectedRequestId :: Maybe FetchRequestId
  }
  deriving (Eq, Show)
instance FromJSON FetchRequestPaused where
  parseJSON = A.withObject "FetchRequestPaused" $ \o -> FetchRequestPaused
    <$> o A..: "requestId"
    <*> o A..: "request"
    <*> o A..: "frameId"
    <*> o A..: "resourceType"
    <*> o A..:? "responseErrorReason"
    <*> o A..:? "responseStatusCode"
    <*> o A..:? "responseStatusText"
    <*> o A..:? "responseHeaders"
    <*> o A..:? "networkId"
    <*> o A..:? "redirectedRequestId"
instance Event FetchRequestPaused where
  eventName _ = "Fetch.requestPaused"

data FetchAuthRequired = FetchAuthRequired
  {
    fetchAuthRequiredRequestId :: FetchRequestId,
    fetchAuthRequiredRequest :: DOMPageNetworkEmulationSecurity.NetworkRequest,
    fetchAuthRequiredFrameId :: DOMPageNetworkEmulationSecurity.PageFrameId,
    fetchAuthRequiredResourceType :: DOMPageNetworkEmulationSecurity.NetworkResourceType,
  | Details of the Authorization Challenge encountered .
    If this is set , client should respond with  that
    fetchAuthRequiredAuthChallenge :: FetchAuthChallenge
  }
  deriving (Eq, Show)
instance FromJSON FetchAuthRequired where
  parseJSON = A.withObject "FetchAuthRequired" $ \o -> FetchAuthRequired
    <$> o A..: "requestId"
    <*> o A..: "request"
    <*> o A..: "frameId"
    <*> o A..: "resourceType"
    <*> o A..: "authChallenge"
instance Event FetchAuthRequired where
  eventName _ = "Fetch.authRequired"


data PFetchDisable = PFetchDisable
  deriving (Eq, Show)
pFetchDisable
  :: PFetchDisable
pFetchDisable
  = PFetchDisable
instance ToJSON PFetchDisable where
  toJSON _ = A.Null
instance Command PFetchDisable where
  type CommandResponse PFetchDisable = ()
  commandName _ = "Fetch.disable"
  fromJSON = const . A.Success . const ()

    calls one of failRequest , fulfillRequest or  / continueWithAuth .

data PFetchEnable = PFetchEnable
  {
    pFetchEnablePatterns :: Maybe [FetchRequestPattern],
    pFetchEnableHandleAuthRequests :: Maybe Bool
  }
  deriving (Eq, Show)
pFetchEnable
  :: PFetchEnable
pFetchEnable
  = PFetchEnable
    Nothing
    Nothing
instance ToJSON PFetchEnable where
  toJSON p = A.object $ catMaybes [
    ("patterns" A..=) <$> (pFetchEnablePatterns p),
    ("handleAuthRequests" A..=) <$> (pFetchEnableHandleAuthRequests p)
    ]
instance Command PFetchEnable where
  type CommandResponse PFetchEnable = ()
  commandName _ = "Fetch.enable"
  fromJSON = const . A.Success . const ()


data PFetchFailRequest = PFetchFailRequest
  {
    pFetchFailRequestRequestId :: FetchRequestId,
    pFetchFailRequestErrorReason :: DOMPageNetworkEmulationSecurity.NetworkErrorReason
  }
  deriving (Eq, Show)
pFetchFailRequest
  :: FetchRequestId
  -> DOMPageNetworkEmulationSecurity.NetworkErrorReason
  -> PFetchFailRequest
pFetchFailRequest
  arg_pFetchFailRequestRequestId
  arg_pFetchFailRequestErrorReason
  = PFetchFailRequest
    arg_pFetchFailRequestRequestId
    arg_pFetchFailRequestErrorReason
instance ToJSON PFetchFailRequest where
  toJSON p = A.object $ catMaybes [
    ("requestId" A..=) <$> Just (pFetchFailRequestRequestId p),
    ("errorReason" A..=) <$> Just (pFetchFailRequestErrorReason p)
    ]
instance Command PFetchFailRequest where
  type CommandResponse PFetchFailRequest = ()
  commandName _ = "Fetch.failRequest"
  fromJSON = const . A.Success . const ()


data PFetchFulfillRequest = PFetchFulfillRequest
  {
    pFetchFulfillRequestRequestId :: FetchRequestId,
    pFetchFulfillRequestResponseCode :: Int,
    pFetchFulfillRequestResponseHeaders :: Maybe [FetchHeaderEntry],
    pFetchFulfillRequestBinaryResponseHeaders :: Maybe T.Text,
    pFetchFulfillRequestBody :: Maybe T.Text,
    pFetchFulfillRequestResponsePhrase :: Maybe T.Text
  }
  deriving (Eq, Show)
pFetchFulfillRequest
  :: FetchRequestId
  -> Int
  -> PFetchFulfillRequest
pFetchFulfillRequest
  arg_pFetchFulfillRequestRequestId
  arg_pFetchFulfillRequestResponseCode
  = PFetchFulfillRequest
    arg_pFetchFulfillRequestRequestId
    arg_pFetchFulfillRequestResponseCode
    Nothing
    Nothing
    Nothing
    Nothing
instance ToJSON PFetchFulfillRequest where
  toJSON p = A.object $ catMaybes [
    ("requestId" A..=) <$> Just (pFetchFulfillRequestRequestId p),
    ("responseCode" A..=) <$> Just (pFetchFulfillRequestResponseCode p),
    ("responseHeaders" A..=) <$> (pFetchFulfillRequestResponseHeaders p),
    ("binaryResponseHeaders" A..=) <$> (pFetchFulfillRequestBinaryResponseHeaders p),
    ("body" A..=) <$> (pFetchFulfillRequestBody p),
    ("responsePhrase" A..=) <$> (pFetchFulfillRequestResponsePhrase p)
    ]
instance Command PFetchFulfillRequest where
  type CommandResponse PFetchFulfillRequest = ()
  commandName _ = "Fetch.fulfillRequest"
  fromJSON = const . A.Success . const ()


data PFetchContinueRequest = PFetchContinueRequest
  {
    pFetchContinueRequestRequestId :: FetchRequestId,
    pFetchContinueRequestUrl :: Maybe T.Text,
    pFetchContinueRequestMethod :: Maybe T.Text,
    pFetchContinueRequestPostData :: Maybe T.Text,
    pFetchContinueRequestHeaders :: Maybe [FetchHeaderEntry],
    pFetchContinueRequestInterceptResponse :: Maybe Bool
  }
  deriving (Eq, Show)
pFetchContinueRequest
  :: FetchRequestId
  -> PFetchContinueRequest
pFetchContinueRequest
  arg_pFetchContinueRequestRequestId
  = PFetchContinueRequest
    arg_pFetchContinueRequestRequestId
    Nothing
    Nothing
    Nothing
    Nothing
    Nothing
instance ToJSON PFetchContinueRequest where
  toJSON p = A.object $ catMaybes [
    ("requestId" A..=) <$> Just (pFetchContinueRequestRequestId p),
    ("url" A..=) <$> (pFetchContinueRequestUrl p),
    ("method" A..=) <$> (pFetchContinueRequestMethod p),
    ("postData" A..=) <$> (pFetchContinueRequestPostData p),
    ("headers" A..=) <$> (pFetchContinueRequestHeaders p),
    ("interceptResponse" A..=) <$> (pFetchContinueRequestInterceptResponse p)
    ]
instance Command PFetchContinueRequest where
  type CommandResponse PFetchContinueRequest = ()
  commandName _ = "Fetch.continueRequest"
  fromJSON = const . A.Success . const ()


  | Parameters of the ' Fetch.continueWithAuth ' command .
data PFetchContinueWithAuth = PFetchContinueWithAuth
  {
    pFetchContinueWithAuthRequestId :: FetchRequestId,
    pFetchContinueWithAuthAuthChallengeResponse :: FetchAuthChallengeResponse
  }
  deriving (Eq, Show)
pFetchContinueWithAuth
  :: FetchRequestId
  -> FetchAuthChallengeResponse
  -> PFetchContinueWithAuth
pFetchContinueWithAuth
  arg_pFetchContinueWithAuthRequestId
  arg_pFetchContinueWithAuthAuthChallengeResponse
  = PFetchContinueWithAuth
    arg_pFetchContinueWithAuthRequestId
    arg_pFetchContinueWithAuthAuthChallengeResponse
instance ToJSON PFetchContinueWithAuth where
  toJSON p = A.object $ catMaybes [
    ("requestId" A..=) <$> Just (pFetchContinueWithAuthRequestId p),
    ("authChallengeResponse" A..=) <$> Just (pFetchContinueWithAuthAuthChallengeResponse p)
    ]
instance Command PFetchContinueWithAuth where
  type CommandResponse PFetchContinueWithAuth = ()
  commandName _ = "Fetch.continueWithAuth"
  fromJSON = const . A.Success . const ()


data PFetchContinueResponse = PFetchContinueResponse
  {
    pFetchContinueResponseRequestId :: FetchRequestId,
    pFetchContinueResponseResponseCode :: Maybe Int,
    pFetchContinueResponseResponsePhrase :: Maybe T.Text,
    pFetchContinueResponseResponseHeaders :: Maybe [FetchHeaderEntry],
    pFetchContinueResponseBinaryResponseHeaders :: Maybe T.Text
  }
  deriving (Eq, Show)
pFetchContinueResponse
  :: FetchRequestId
  -> PFetchContinueResponse
pFetchContinueResponse
  arg_pFetchContinueResponseRequestId
  = PFetchContinueResponse
    arg_pFetchContinueResponseRequestId
    Nothing
    Nothing
    Nothing
    Nothing
instance ToJSON PFetchContinueResponse where
  toJSON p = A.object $ catMaybes [
    ("requestId" A..=) <$> Just (pFetchContinueResponseRequestId p),
    ("responseCode" A..=) <$> (pFetchContinueResponseResponseCode p),
    ("responsePhrase" A..=) <$> (pFetchContinueResponseResponsePhrase p),
    ("responseHeaders" A..=) <$> (pFetchContinueResponseResponseHeaders p),
    ("binaryResponseHeaders" A..=) <$> (pFetchContinueResponseBinaryResponseHeaders p)
    ]
instance Command PFetchContinueResponse where
  type CommandResponse PFetchContinueResponse = ()
  commandName _ = "Fetch.continueResponse"
  fromJSON = const . A.Success . const ()

    returned as a single string . May only be issued for a request that

data PFetchGetResponseBody = PFetchGetResponseBody
  {
    pFetchGetResponseBodyRequestId :: FetchRequestId
  }
  deriving (Eq, Show)
pFetchGetResponseBody
  :: FetchRequestId
  -> PFetchGetResponseBody
pFetchGetResponseBody
  arg_pFetchGetResponseBodyRequestId
  = PFetchGetResponseBody
    arg_pFetchGetResponseBodyRequestId
instance ToJSON PFetchGetResponseBody where
  toJSON p = A.object $ catMaybes [
    ("requestId" A..=) <$> Just (pFetchGetResponseBodyRequestId p)
    ]
data FetchGetResponseBody = FetchGetResponseBody
  {
    fetchGetResponseBodyBody :: T.Text,
    fetchGetResponseBodyBase64Encoded :: Bool
  }
  deriving (Eq, Show)
instance FromJSON FetchGetResponseBody where
  parseJSON = A.withObject "FetchGetResponseBody" $ \o -> FetchGetResponseBody
    <$> o A..: "body"
    <*> o A..: "base64Encoded"
instance Command PFetchGetResponseBody where
  type CommandResponse PFetchGetResponseBody = FetchGetResponseBody
  commandName _ = "Fetch.getResponseBody"

    The stream only supports sequential read ,  will fail if the position

data PFetchTakeResponseBodyAsStream = PFetchTakeResponseBodyAsStream
  {
    pFetchTakeResponseBodyAsStreamRequestId :: FetchRequestId
  }
  deriving (Eq, Show)
pFetchTakeResponseBodyAsStream
  :: FetchRequestId
  -> PFetchTakeResponseBodyAsStream
pFetchTakeResponseBodyAsStream
  arg_pFetchTakeResponseBodyAsStreamRequestId
  = PFetchTakeResponseBodyAsStream
    arg_pFetchTakeResponseBodyAsStreamRequestId
instance ToJSON PFetchTakeResponseBodyAsStream where
  toJSON p = A.object $ catMaybes [
    ("requestId" A..=) <$> Just (pFetchTakeResponseBodyAsStreamRequestId p)
    ]
data FetchTakeResponseBodyAsStream = FetchTakeResponseBodyAsStream
  {
    fetchTakeResponseBodyAsStreamStream :: IO.IOStreamHandle
  }
  deriving (Eq, Show)
instance FromJSON FetchTakeResponseBodyAsStream where
  parseJSON = A.withObject "FetchTakeResponseBodyAsStream" $ \o -> FetchTakeResponseBodyAsStream
    <$> o A..: "stream"
instance Command PFetchTakeResponseBodyAsStream where
  type CommandResponse PFetchTakeResponseBodyAsStream = FetchTakeResponseBodyAsStream
  commandName _ = "Fetch.takeResponseBodyAsStream"

