{-# LANGUAGE DataKinds         #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE TemplateHaskell   #-}
{-# LANGUAGE TypeApplications  #-}
{-# LANGUAGE TypeFamilies      #-}

module PlutusExample.PlutusVersion1.Loop
  ( loopScript
  , loopScriptShortBs
  ) where

import Prelude hiding (pred, ($), (&&), (<), (==))

import Cardano.Api.Shelley (PlutusScript (..), PlutusScriptV1)

import Codec.Serialise
import Data.ByteString.Lazy qualified as LBS
import Data.ByteString.Short qualified as SBS

import Plutus.V1.Ledger.Scripts qualified as Plutus
import PlutusTx
import PlutusTx.Builtins (unsafeDataAsI)
import PlutusTx.Prelude hiding (Semigroup (..), unless, (.))

{-# INLINABLE mkValidator #-}
mkValidator :: BuiltinData -> BuiltinData -> BuiltinData -> ()
mkValidator :: BuiltinData -> BuiltinData -> BuiltinData -> ()
mkValidator BuiltinData
_datum BuiltinData
redeemer BuiltinData
_txContext
  = if Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
1000000
       then BuiltinString -> ()
forall a. BuiltinString -> a
traceError BuiltinString
"redeemer is < 1000000"
       else Integer -> ()
forall a. (Eq a, Num a, Enum a) => a -> ()
loop Integer
n
  where
    n :: Integer
n = BuiltinData -> Integer
unsafeDataAsI BuiltinData
redeemer
    loop :: a -> ()
loop a
i = if a
i a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
1000000 then () else a -> ()
loop (a -> ()) -> a -> ()
forall a b. (a -> b) -> a -> b
$ a -> a
forall a. Enum a => a -> a
pred a
i

validator :: Plutus.Validator
validator :: Validator
validator = CompiledCode (BuiltinData -> BuiltinData -> BuiltinData -> ())
-> Validator
Plutus.mkValidatorScript $$(PlutusTx.compile [|| mkValidator ||])

script :: Plutus.Script
script :: Script
script = Validator -> Script
Plutus.unValidatorScript Validator
validator

loopScriptShortBs :: SBS.ShortByteString
loopScriptShortBs :: ShortByteString
loopScriptShortBs = ByteString -> ShortByteString
SBS.toShort (ByteString -> ShortByteString)
-> (ByteString -> ByteString) -> ByteString -> ShortByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
LBS.toStrict (ByteString -> ShortByteString) -> ByteString -> ShortByteString
forall a b. (a -> b) -> a -> b
$ Script -> ByteString
forall a. Serialise a => a -> ByteString
serialise Script
script

loopScript :: PlutusScript PlutusScriptV1
loopScript :: PlutusScript PlutusScriptV1
loopScript = ShortByteString -> PlutusScript PlutusScriptV1
forall lang. ShortByteString -> PlutusScript lang
PlutusScriptSerialised ShortByteString
loopScriptShortBs