{-# LANGUAGE DataKinds          #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE KindSignatures     #-}
{-# LANGUAGE OverloadedStrings  #-}
{-# LANGUAGE RecordWildCards    #-}

module PlutusTx.Blueprint.Argument where

import Prelude

import Data.Aeson (ToJSON (..))
import Data.Aeson.Extra (buildObject, optionalField, requiredField)
import Data.Kind (Type)
import Data.Set (Set)
import Data.Text (Text)
import PlutusTx.Blueprint.Parameter (oneOfASet)
import PlutusTx.Blueprint.Purpose (Purpose)
import PlutusTx.Blueprint.Schema (Schema)

-- | Blueprint that defines a validator's runtime argument: datum or redeemer.
data ArgumentBlueprint (referencedTypes :: [Type]) = MkArgumentBlueprint
  { forall (referencedTypes :: [*]).
ArgumentBlueprint referencedTypes -> Maybe Text
argumentTitle       :: Maybe Text
  -- ^ A short and descriptive name for the redeemer or datum.
  , forall (referencedTypes :: [*]).
ArgumentBlueprint referencedTypes -> Maybe Text
argumentDescription :: Maybe Text
  -- ^ An informative description of the redeemer or datum.
  , forall (referencedTypes :: [*]).
ArgumentBlueprint referencedTypes -> Set Purpose
argumentPurpose     :: Set Purpose
  -- ^ A possibly empty set of purposes for the redeemer or datum.
  , forall (referencedTypes :: [*]).
ArgumentBlueprint referencedTypes -> Schema referencedTypes
argumentSchema      :: Schema referencedTypes
  -- ^ A Plutus Data Schema.
  }
  deriving stock (Int -> ArgumentBlueprint referencedTypes -> ShowS
[ArgumentBlueprint referencedTypes] -> ShowS
ArgumentBlueprint referencedTypes -> String
(Int -> ArgumentBlueprint referencedTypes -> ShowS)
-> (ArgumentBlueprint referencedTypes -> String)
-> ([ArgumentBlueprint referencedTypes] -> ShowS)
-> Show (ArgumentBlueprint referencedTypes)
forall (referencedTypes :: [*]).
Int -> ArgumentBlueprint referencedTypes -> ShowS
forall (referencedTypes :: [*]).
[ArgumentBlueprint referencedTypes] -> ShowS
forall (referencedTypes :: [*]).
ArgumentBlueprint referencedTypes -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall (referencedTypes :: [*]).
Int -> ArgumentBlueprint referencedTypes -> ShowS
showsPrec :: Int -> ArgumentBlueprint referencedTypes -> ShowS
$cshow :: forall (referencedTypes :: [*]).
ArgumentBlueprint referencedTypes -> String
show :: ArgumentBlueprint referencedTypes -> String
$cshowList :: forall (referencedTypes :: [*]).
[ArgumentBlueprint referencedTypes] -> ShowS
showList :: [ArgumentBlueprint referencedTypes] -> ShowS
Show, ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes -> Bool
(ArgumentBlueprint referencedTypes
 -> ArgumentBlueprint referencedTypes -> Bool)
-> (ArgumentBlueprint referencedTypes
    -> ArgumentBlueprint referencedTypes -> Bool)
-> Eq (ArgumentBlueprint referencedTypes)
forall (referencedTypes :: [*]).
ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall (referencedTypes :: [*]).
ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes -> Bool
== :: ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes -> Bool
$c/= :: forall (referencedTypes :: [*]).
ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes -> Bool
/= :: ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes -> Bool
Eq, Eq (ArgumentBlueprint referencedTypes)
Eq (ArgumentBlueprint referencedTypes) =>
(ArgumentBlueprint referencedTypes
 -> ArgumentBlueprint referencedTypes -> Ordering)
-> (ArgumentBlueprint referencedTypes
    -> ArgumentBlueprint referencedTypes -> Bool)
-> (ArgumentBlueprint referencedTypes
    -> ArgumentBlueprint referencedTypes -> Bool)
-> (ArgumentBlueprint referencedTypes
    -> ArgumentBlueprint referencedTypes -> Bool)
-> (ArgumentBlueprint referencedTypes
    -> ArgumentBlueprint referencedTypes -> Bool)
-> (ArgumentBlueprint referencedTypes
    -> ArgumentBlueprint referencedTypes
    -> ArgumentBlueprint referencedTypes)
-> (ArgumentBlueprint referencedTypes
    -> ArgumentBlueprint referencedTypes
    -> ArgumentBlueprint referencedTypes)
-> Ord (ArgumentBlueprint referencedTypes)
ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes -> Bool
ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes -> Ordering
ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes
forall (referencedTypes :: [*]).
Eq (ArgumentBlueprint referencedTypes)
forall (referencedTypes :: [*]).
ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes -> Bool
forall (referencedTypes :: [*]).
ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes -> Ordering
forall (referencedTypes :: [*]).
ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: forall (referencedTypes :: [*]).
ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes -> Ordering
compare :: ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes -> Ordering
$c< :: forall (referencedTypes :: [*]).
ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes -> Bool
< :: ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes -> Bool
$c<= :: forall (referencedTypes :: [*]).
ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes -> Bool
<= :: ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes -> Bool
$c> :: forall (referencedTypes :: [*]).
ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes -> Bool
> :: ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes -> Bool
$c>= :: forall (referencedTypes :: [*]).
ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes -> Bool
>= :: ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes -> Bool
$cmax :: forall (referencedTypes :: [*]).
ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes
max :: ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes
$cmin :: forall (referencedTypes :: [*]).
ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes
min :: ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes
-> ArgumentBlueprint referencedTypes
Ord)

instance ToJSON (ArgumentBlueprint referencedTypes) where
  toJSON :: ArgumentBlueprint referencedTypes -> Value
toJSON MkArgumentBlueprint{Maybe Text
Set Purpose
Schema referencedTypes
argumentTitle :: forall (referencedTypes :: [*]).
ArgumentBlueprint referencedTypes -> Maybe Text
argumentDescription :: forall (referencedTypes :: [*]).
ArgumentBlueprint referencedTypes -> Maybe Text
argumentPurpose :: forall (referencedTypes :: [*]).
ArgumentBlueprint referencedTypes -> Set Purpose
argumentSchema :: forall (referencedTypes :: [*]).
ArgumentBlueprint referencedTypes -> Schema referencedTypes
argumentTitle :: Maybe Text
argumentDescription :: Maybe Text
argumentPurpose :: Set Purpose
argumentSchema :: Schema referencedTypes
..} =
    (Object -> Object) -> Value
buildObject ((Object -> Object) -> Value) -> (Object -> Object) -> Value
forall a b. (a -> b) -> a -> b
$
      Key -> Schema referencedTypes -> Object -> Object
forall a. ToJSON a => Key -> a -> Object -> Object
requiredField Key
"schema" Schema referencedTypes
argumentSchema
        (Object -> Object) -> (Object -> Object) -> Object -> Object
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Maybe Text -> Object -> Object
forall a. ToJSON a => Key -> Maybe a -> Object -> Object
optionalField Key
"title" Maybe Text
argumentTitle
        (Object -> Object) -> (Object -> Object) -> Object -> Object
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Maybe Text -> Object -> Object
forall a. ToJSON a => Key -> Maybe a -> Object -> Object
optionalField Key
"description" Maybe Text
argumentDescription
        (Object -> Object) -> (Object -> Object) -> Object -> Object
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Maybe Value -> Object -> Object
forall a. ToJSON a => Key -> Maybe a -> Object -> Object
optionalField Key
"purpose" (Set Purpose -> Maybe Value
forall a. ToJSON a => Set a -> Maybe Value
oneOfASet Set Purpose
argumentPurpose)