content: {-# LANGUAGE DeriveAnyClass #-}
  
  module WebDriverPreCore.BiDi.Storage where
  
  {-
  create types to represent the remote and local end for storage:
  
  1. preface singleton data constructors (ie the constructor for types with only one type constructor) with Mk
  2. use newtypes where possible
  3. ordering - order types such that types that are used by a type are declared immediately below that type in the order they are used
  4. derive Show, Eq and Generic for all types
  5. use Text rather than String
  5. use the cddl in this file remote first under the -- ######### Remote ######### header
    then local under the -- ######### Local ######### header
  7. Avoid using Parameters suffix in type and data constructor names
  8. leave this comment at the top of the file
  -}
  
  import Data.Aeson (FromJSON, ToJSON (..), Value)
  import Data.Text (Text)
  import GHC.Generics (Generic)
  import WebDriverPreCore.BiDi.BrowsingContext qualified as BrowsingContext
  import WebDriverPreCore.BiDi.Network qualified as Network
  import WebDriverPreCore.Internal.AesonUtils (enumCamelCase)
  import Prelude (Bool, Eq, Int, Maybe, Show)
  
  -- ######### Remote #########
  
  -- | Partition key for storage operations
  data PartitionKey = MkPartitionKey
    { userContext :: Maybe Text,
      sourceOrigin :: Maybe Text
    }
    deriving (Show, Eq, Generic)
  
  instance FromJSON PartitionKey
  
  instance ToJSON PartitionKey
  
  -- | Result of getting cookies
  data GetCookiesResult = MkGetCookiesResult
    { cookies :: [Network.Cookie],
      partitionKey :: PartitionKey
    }
    deriving (Show, Eq, Generic)
  
  instance FromJSON GetCookiesResult
  
  -- | Result of setting a cookie
  newtype SetCookieResult = MkSetCookieResult
    { partitionKey :: PartitionKey
    }
    deriving (Show, Eq, Generic)
  
  instance FromJSON SetCookieResult
  
  -- | Result of deleting cookies
  newtype DeleteCookiesResult = MkDeleteCookiesResult
    { partitionKey :: PartitionKey
    }
    deriving (Show, Eq, Generic)
  
  instance FromJSON DeleteCookiesResult
  
  -- ######### Local #########
  
  -- | Parameters for getting cookies
  data GetCookies = MkGetCookies
    { filter :: Maybe CookieFilter,
      partition :: Maybe PartitionDescriptor
    }
    deriving (Show, Eq, Generic)
  
  instance ToJSON GetCookies
  
  -- | Filter for cookie operations
  data CookieFilter = MkCookieFilter
    { name :: Maybe Text,
      value :: Maybe Network.BytesValue,
      domain :: Maybe Text,
      path :: Maybe Text,
      size :: Maybe Int,
      httpOnly :: Maybe Bool,
      secure :: Maybe Bool,
      sameSite :: Maybe Network.SameSite,
      expiry :: Maybe Int
    }
    deriving (Show, Eq, Generic)
  
  instance FromJSON CookieFilter
  
  instance ToJSON CookieFilter
  
  -- | Descriptor for a partition
  data PartitionDescriptor
    = BrowsingContextPartition BrowsingContextPartitionDescriptor
    | StorageKeyPartition StorageKeyPartitionDescriptor
    deriving (Show, Eq, Generic)
  
  instance FromJSON PartitionDescriptor
  
  instance ToJSON PartitionDescriptor where
    toJSON :: PartitionDescriptor -> Value
    toJSON = enumCamelCase
  
  -- | Browsing context partition descriptor
  newtype BrowsingContextPartitionDescriptor = MkBrowsingContextPartitionDescriptor
    { context :: BrowsingContext.BrowsingContextId
    }
    deriving (Show, Eq, Generic)
  
  instance FromJSON BrowsingContextPartitionDescriptor
  
  instance ToJSON BrowsingContextPartitionDescriptor
  
  -- | Storage key partition descriptor
  data StorageKeyPartitionDescriptor = MkStorageKeyPartitionDescriptor
    { userContext :: Maybe Text,
      sourceOrigin :: Maybe Text
    }
    deriving (Show, Eq, Generic)
  
  instance FromJSON StorageKeyPartitionDescriptor
  
  instance ToJSON StorageKeyPartitionDescriptor
  
  -- | Parameters for setting a cookie
  data SetCookie = MkSetCookie
    { cookie :: PartialCookie,
      partition :: Maybe PartitionDescriptor
    }
    deriving (Show, Eq, Generic)
  
  instance ToJSON SetCookie
  
  -- | Partial cookie for setting
  data PartialCookie = MkPartialCookie
    { name :: Text,
      value :: Network.BytesValue,
      domain :: Text,
      path :: Maybe Text,
      httpOnly :: Maybe Bool,
      secure :: Maybe Bool,
      sameSite :: Maybe Network.SameSite,
      expiry :: Maybe Int
    }
    deriving (Show, Eq, Generic)
  
  instance FromJSON PartialCookie
  
  instance ToJSON PartialCookie
  
  -- | Parameters for deleting cookies
  data DeleteCookies = MkDeleteCookies
    { filter :: Maybe CookieFilter,
      partition :: Maybe PartitionDescriptor
    }
    deriving (Show, Eq, Generic)
  
  instance ToJSON DeleteCookies
  