-- | Allows specifying entrypoints without declaring 'ParamterHasEntryPoints'
-- instance.
module Lorentz.EntryPoints.Manual
  ( ParameterWrapper (..)
  ) where

import Control.Lens (Wrapped)
import qualified Data.Kind as Kind

import Lorentz.Constraints
import Lorentz.EntryPoints.Core
import Michelson.Typed

-- | Wrap parameter into this to locally assign a way to derive entrypoints for
-- it.
newtype ParameterWrapper (deriv :: Kind.Type) cp = ParameterWrapper { unParameterWraper :: cp }
  deriving stock Generic
  deriving anyclass IsoValue

instance Wrapped (ParameterWrapper deriv cp)

-- Helper for implementing @instance ParameterHasEntryPoints ParameterWrapper@.
data PwDeriv deriv
instance EntryPointsDerivation deriv cp =>
         EntryPointsDerivation (PwDeriv deriv) (ParameterWrapper deriv cp) where
  type EpdAllEntryPoints (PwDeriv deriv) (ParameterWrapper deriv cp) =
    EpdAllEntryPoints deriv cp
  type EpdLookupEntryPoint (PwDeriv deriv) (ParameterWrapper deriv cp) =
    EpdLookupEntryPoint deriv cp
  epdNotes = epdNotes @deriv @cp
  epdCall = epdCall @deriv @cp

instance ( NiceParameter cp
         , EntryPointsDerivation epd cp
         , RequireAllUniqueEntryPoints' epd cp
         ) =>
         ParameterHasEntryPoints (ParameterWrapper epd cp) where
  type ParameterEntryPointsDerivation (ParameterWrapper epd cp) = PwDeriv epd