-- SPDX-FileCopyrightText: 2020 Tocqueville Group
--
-- SPDX-License-Identifier: LicenseRef-MIT-TQ

-- TODO: Replace 'Empty' with 'Never' from morley
{-# OPTIONS_GHC -Wno-deprecations #-}

-- | UpgradeableCounterSdu demonstrates the implementation of a simple contract
--   that has upgradeable storage, interface, and implementation and uses
--   storage-driven upgrades. Aside from the latter, this contract is similar
--   to "UpgradeableCounter".
--
--   In the first version it stores a Natural and allows to add some value
--   to it.
--
--   The second version changes the type of the stored value to Integer,
--   and instead of providing Add Natural and Inc () endpoints, it
--   just allows to increment or decrement the current value.
--
--   While the contract does not have any advanced functionality, it provides
--   a birds-eye view on all the aspects of the upgradeable contracts concept
--   and serves as an example on how to apply this concept.


module Lorentz.Contracts.UpgradeableCounterSdu
  ( CounterSduV
  , Parameter(..)
  , Storage
  , Permanent (..)
  , upgradeableCounterContractSdu
  , mkEmptyStorage
  ) where

import Lorentz

import Lorentz.Contracts.Upgradeable.Common

-- | Version identifier for this contract.
--
-- It a bit differs from how we do in other contracts - this type is supposed
-- to be used in all versions of the contract, but it has type parameter which
-- is supposed to designate contract version.
data CounterSduV (v :: Nat) :: VersionKind

data Permanent
  = GetCounter (Void_ () Integer)
  | GetNothing Empty
  deriving stock (forall x. Permanent -> Rep Permanent x)
-> (forall x. Rep Permanent x -> Permanent) -> Generic Permanent
forall x. Rep Permanent x -> Permanent
forall x. Permanent -> Rep Permanent x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Permanent x -> Permanent
$cfrom :: forall x. Permanent -> Rep Permanent x
Generic
  deriving anyclass (WellTypedToT Permanent
WellTypedToT Permanent
-> (Permanent -> Value (ToT Permanent))
-> (Value (ToT Permanent) -> Permanent)
-> IsoValue Permanent
Value (ToT Permanent) -> Permanent
Permanent -> Value (ToT Permanent)
forall a.
WellTypedToT a
-> (a -> Value (ToT a)) -> (Value (ToT a) -> a) -> IsoValue a
fromVal :: Value (ToT Permanent) -> Permanent
$cfromVal :: Value (ToT Permanent) -> Permanent
toVal :: Permanent -> Value (ToT Permanent)
$ctoVal :: Permanent -> Value (ToT Permanent)
$cp1IsoValue :: WellTypedToT Permanent
IsoValue, AnnOptions
FollowEntrypointFlag -> Notes (ToT Permanent)
(FollowEntrypointFlag -> Notes (ToT Permanent))
-> AnnOptions -> HasAnnotation Permanent
forall a.
(FollowEntrypointFlag -> Notes (ToT a))
-> AnnOptions -> HasAnnotation a
annOptions :: AnnOptions
$cannOptions :: AnnOptions
getAnnotation :: FollowEntrypointFlag -> Notes (ToT Permanent)
$cgetAnnotation :: FollowEntrypointFlag -> Notes (ToT Permanent)
HasAnnotation)

instance ParameterHasEntrypoints Permanent where
  type ParameterEntrypointsDerivation Permanent = EpdPlain

instance TypeHasDoc Permanent where
  typeDocMdDescription :: Markdown
typeDocMdDescription = Markdown
"Parameter for permanent entrypoints."

deriving via (EmptyContractVersion Permanent)
  instance KnownContractVersion (CounterSduV 0)

upgradeableCounterContractSdu :: UpgradeableContract (CounterSduV 0)
upgradeableCounterContractSdu :: UpgradeableContract (CounterSduV 0)
upgradeableCounterContractSdu = UpgradeableContract (CounterSduV 0)
forall (ver :: VersionKind).
(NiceVersion ver, NiceParameterFull (Parameter ver)) =>
UpgradeableContract ver
upgradeableContract