{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DerivingVia    #-}

{-# OPTIONS_GHC -fno-warn-orphans #-}

module Ledger.Scripts.Orphans where

import Ledger.Builtins.Orphans ()

import Codec.CBOR.Extras (SerialiseViaFlat (..))
import Data.Aeson.Extras qualified as JSON
import Plutus.V1.Ledger.Scripts

import Data.Aeson (FromJSON (parseJSON), FromJSONKey, ToJSON (toJSON), ToJSONKey)
import Data.Aeson qualified as JSON

import Codec.Serialise (Serialise)
import Data.Hashable (Hashable)

{- Note [JSON instances for Script]
The JSON instances for Script are partially hand-written rather than going via the Serialise
instance directly. The reason for this is to *avoid* the size checks that are in place in the
Serialise instance. These are only useful for deserialisation checks on-chain, whereas the
JSON instances are used for e.g. transmitting validation events, which often include scripts
with the data arguments applied (which can be very big!).
-}

instance ToJSON Script where
    -- See note [JSON instances for Script]
    toJSON :: Script -> Value
toJSON (Script Program DeBruijn DefaultUni DefaultFun ()
p) = Text -> Value
JSON.String (Text -> Value) -> Text -> Value
forall a b. (a -> b) -> a -> b
$ SerialiseViaFlat (Program DeBruijn DefaultUni DefaultFun ())
-> Text
forall a. Serialise a => a -> Text
JSON.encodeSerialise (Program DeBruijn DefaultUni DefaultFun ()
-> SerialiseViaFlat (Program DeBruijn DefaultUni DefaultFun ())
forall a. a -> SerialiseViaFlat a
SerialiseViaFlat Program DeBruijn DefaultUni DefaultFun ()
p)

instance FromJSON Script where
    -- See note [JSON instances for Script]
    parseJSON :: Value -> Parser Script
parseJSON Value
v = do
        (SerialiseViaFlat Program DeBruijn DefaultUni DefaultFun ()
p) <- Value
-> Parser
     (SerialiseViaFlat (Program DeBruijn DefaultUni DefaultFun ()))
forall a. Serialise a => Value -> Parser a
JSON.decodeSerialise Value
v
        Script -> Parser Script
forall (m :: * -> *) a. Monad m => a -> m a
return (Script -> Parser Script) -> Script -> Parser Script
forall a b. (a -> b) -> a -> b
$ Program DeBruijn DefaultUni DefaultFun () -> Script
Script Program DeBruijn DefaultUni DefaultFun ()
p

deriving anyclass instance ToJSON DatumHash
deriving anyclass instance FromJSON DatumHash
deriving anyclass instance ToJSONKey DatumHash
deriving anyclass instance FromJSONKey DatumHash
deriving newtype instance Hashable DatumHash
deriving newtype instance Serialise DatumHash

deriving anyclass instance ToJSON RedeemerHash
deriving anyclass instance FromJSON RedeemerHash
deriving anyclass instance ToJSONKey RedeemerHash
deriving anyclass instance FromJSONKey RedeemerHash
deriving newtype instance Hashable RedeemerHash
deriving newtype instance Serialise RedeemerHash

deriving anyclass instance ToJSON MintingPolicyHash
deriving anyclass instance FromJSON MintingPolicyHash
deriving anyclass instance ToJSONKey MintingPolicyHash
deriving anyclass instance FromJSONKey MintingPolicyHash
deriving newtype instance Hashable MintingPolicyHash
deriving newtype instance Serialise MintingPolicyHash

deriving anyclass instance ToJSON StakeValidatorHash
deriving anyclass instance FromJSON StakeValidatorHash
deriving anyclass instance ToJSONKey StakeValidatorHash
deriving anyclass instance FromJSONKey StakeValidatorHash
deriving newtype instance Hashable StakeValidatorHash
deriving newtype instance Serialise StakeValidatorHash

deriving anyclass instance ToJSON ScriptHash
deriving anyclass instance FromJSON ScriptHash
deriving anyclass instance ToJSONKey ScriptHash
deriving anyclass instance FromJSONKey ScriptHash
deriving newtype instance Hashable ScriptHash
deriving newtype instance Serialise ScriptHash

deriving anyclass instance ToJSON ValidatorHash
deriving anyclass instance FromJSON ValidatorHash
deriving anyclass instance ToJSONKey ValidatorHash
deriving anyclass instance FromJSONKey ValidatorHash
deriving newtype instance Hashable ValidatorHash
deriving newtype instance Serialise ValidatorHash

deriving newtype instance ToJSON Context
deriving newtype instance FromJSON Context

deriving anyclass instance ToJSON StakeValidator
deriving anyclass instance FromJSON StakeValidator

deriving anyclass instance ToJSON MintingPolicy
deriving anyclass instance FromJSON MintingPolicy

deriving anyclass instance ToJSON Validator
deriving anyclass instance FromJSON Validator

deriving anyclass instance ToJSON Redeemer
deriving anyclass instance FromJSON Redeemer
deriving anyclass instance Serialise Redeemer

deriving anyclass instance ToJSON Datum
deriving anyclass instance FromJSON Datum
deriving anyclass instance Serialise Datum