{-# OPTIONS --safe #-}

open import Data.Nat.Properties using (+-0-monoid)
open import Data.Rational using ()

open import Ledger.Prelude
open import Ledger.Conway.Types.GovStructure

module Ledger.Conway.Enact (gs : _) (open GovStructure gs) where

open import Ledger.Conway.GovernanceActions gs


record EnactEnv : Type where
  field
    gid       : GovActionID
    treasury  : Coin
    epoch     : Epoch

record EnactState : Type where
  field
    cc            : HashProtected (Maybe ((Credential  Epoch) × ))
    constitution  : HashProtected (DocHash × Maybe ScriptHash)
    pv            : HashProtected ProtVer
    pparams       : HashProtected PParams
    withdrawals   : RwdAddr  Coin


record HasEnactState {a} (A : Type a) : Type a where
  field EnactStateOf : A  EnactState
open HasEnactState ⦃...⦄ public

instance
  HasPParams-EnactState : HasPParams EnactState
  HasPParams-EnactState .PParamsOf = proj₁  EnactState.pparams

  HasccMaxTermLength-EnactState : HasccMaxTermLength EnactState
  HasccMaxTermLength-EnactState .ccMaxTermLengthOf = PParams.ccMaxTermLength  PParamsOf

  unquoteDecl HasCast-EnactEnv = derive-HasCast
    [ (quote EnactEnv , HasCast-EnactEnv) ]

open EnactState



ccCreds : HashProtected (Maybe ((Credential  Epoch) × ))   Credential
ccCreds (just x   , _)  = dom (x .proj₁)
ccCreds (nothing  , _)  = 

getHash :  {a}  NeedsHash a  Maybe GovActionID
getHash {NoConfidence}     h = just h
getHash {UpdateCommittee}  h = just h
getHash {NewConstitution}  h = just h
getHash {TriggerHF}        h = just h
getHash {ChangePParams}    h = just h
getHash {TreasuryWdrl}     _ = nothing
getHash {Info}             _ = nothing

getHashES : EnactState  GovActionType  Maybe GovActionID
getHashES es NoConfidence       = just (es .cc .proj₂)
getHashES es (UpdateCommittee)  = just (es .cc .proj₂)
getHashES es (NewConstitution)  = just (es .constitution .proj₂)
getHashES es (TriggerHF)        = just (es .pv .proj₂)
getHashES es (ChangePParams)    = just (es .pparams .proj₂)
getHashES es (TreasuryWdrl)     = nothing
getHashES es Info               = nothing


data


  _⊢_⇀⦇_,ENACT⦈_ : EnactEnv  EnactState  GovAction  EnactState  Type


open EnactState

private variable
  s : EnactState
  up : PParamsUpdate
  new : Credential  Epoch
  rem :  Credential
  q : 
  dh : DocHash
  sh : Maybe ScriptHash
  v : ProtVer
  wdrl : RwdAddr  Coin
  t : Coin
  gid : GovActionID
  e : Epoch

instance
  _ = +-0-monoid


open PParams using (ccMaxTermLength)
open EnactState using (cc)
data _⊢_⇀⦇_,ENACT⦈_ where


  Enact-NoConf :
    ───────────────────────────────────────
    $\begin{pmatrix} \,\href{Ledger.Conway.Enact.html#2413}{\htmlId{2631}{\htmlClass{Generalizable}{\text{gid}}}}\, \\ \,\href{Ledger.Conway.Enact.html#2402}{\htmlId{2637}{\htmlClass{Generalizable}{\text{t}}}}\, \\ \,\href{Ledger.Conway.Enact.html#2433}{\htmlId{2641}{\htmlClass{Generalizable}{\text{e}}}}\, \end{pmatrix}$  s ⇀⦇ $\begin{pmatrix} \,\href{Ledger.Conway.GovernanceActions.html#758}{\htmlId{2654}{\htmlClass{InductiveConstructor}{\text{NoConfidence}}}}\, \\ \,\htmlId{2669}{\htmlClass{Symbol}{\text{\_}}}\, \end{pmatrix}$ ,ENACT⦈ record s { cc = nothing , gid }

  Enact-UpdComm : let old      = maybe proj₁  (s .cc .proj₁)
                      maxTerm  = ccMaxTermLengthOf s +ᵉ e
                  in
    ∀[ term  range new ] term  maxTerm
    ───────────────────────────────────────
    $\begin{pmatrix} \,\href{Ledger.Conway.Enact.html#2413}{\htmlId{2948}{\htmlClass{Generalizable}{\text{gid}}}}\, \\ \,\href{Ledger.Conway.Enact.html#2402}{\htmlId{2954}{\htmlClass{Generalizable}{\text{t}}}}\, \\ \,\href{Ledger.Conway.Enact.html#2433}{\htmlId{2958}{\htmlClass{Generalizable}{\text{e}}}}\, \end{pmatrix}$  s ⇀⦇ $\begin{pmatrix} \,\href{Ledger.Conway.GovernanceActions.html#793}{\htmlId{2971}{\htmlClass{InductiveConstructor}{\text{UpdateCommittee}}}}\, \\ (\,\href{Ledger.Conway.Enact.html#2269}{\htmlId{2990}{\htmlClass{Generalizable}{\text{new}}}}\, , \,\href{Ledger.Conway.Enact.html#2296}{\htmlId{2996}{\htmlClass{Generalizable}{\text{rem}}}}\, , \,\href{Ledger.Conway.Enact.html#2317}{\htmlId{3002}{\htmlClass{Generalizable}{\text{q}}}}\,) \end{pmatrix}$ ,ENACT⦈
      record s { cc = just ((new ∪ˡ old)  rem  , q) , gid }

  Enact-NewConst :
    ───────────────────────────────────────
    $\begin{pmatrix} \,\href{Ledger.Conway.Enact.html#2413}{\htmlId{3149}{\htmlClass{Generalizable}{\text{gid}}}}\, \\ \,\href{Ledger.Conway.Enact.html#2402}{\htmlId{3155}{\htmlClass{Generalizable}{\text{t}}}}\, \\ \,\href{Ledger.Conway.Enact.html#2433}{\htmlId{3159}{\htmlClass{Generalizable}{\text{e}}}}\, \end{pmatrix}$  s ⇀⦇ $\begin{pmatrix} \,\href{Ledger.Conway.GovernanceActions.html#828}{\htmlId{3172}{\htmlClass{InductiveConstructor}{\text{NewConstitution}}}}\, \\ (\,\href{Ledger.Conway.Enact.html#2325}{\htmlId{3191}{\htmlClass{Generalizable}{\text{dh}}}}\, , \,\href{Ledger.Conway.Enact.html#2340}{\htmlId{3196}{\htmlClass{Generalizable}{\text{sh}}}}\,) \end{pmatrix}$ ,ENACT⦈ record s { constitution = (dh , sh) , gid }


  Enact-HF :
    ───────────────────────────────────────
    $\begin{pmatrix} \,\href{Ledger.Conway.Enact.html#2413}{\htmlId{3321}{\htmlClass{Generalizable}{\text{gid}}}}\, \\ \,\href{Ledger.Conway.Enact.html#2402}{\htmlId{3327}{\htmlClass{Generalizable}{\text{t}}}}\, \\ \,\href{Ledger.Conway.Enact.html#2433}{\htmlId{3331}{\htmlClass{Generalizable}{\text{e}}}}\, \end{pmatrix}$  s ⇀⦇ $\begin{pmatrix} \,\href{Ledger.Conway.GovernanceActions.html#863}{\htmlId{3344}{\htmlClass{InductiveConstructor}{\text{TriggerHF}}}}\, \\ \,\href{Ledger.Conway.Enact.html#2364}{\htmlId{3356}{\htmlClass{Generalizable}{\text{v}}}}\, \end{pmatrix}$ ,ENACT⦈ record s { pv = v , gid }

  Enact-PParams :
    ───────────────────────────────────────
    $\begin{pmatrix} \,\href{Ledger.Conway.Enact.html#2413}{\htmlId{3465}{\htmlClass{Generalizable}{\text{gid}}}}\, \\ \,\href{Ledger.Conway.Enact.html#2402}{\htmlId{3471}{\htmlClass{Generalizable}{\text{t}}}}\, \\ \,\href{Ledger.Conway.Enact.html#2433}{\htmlId{3475}{\htmlClass{Generalizable}{\text{e}}}}\, \end{pmatrix}$  s ⇀⦇ $\begin{pmatrix} \,\href{Ledger.Conway.GovernanceActions.html#898}{\htmlId{3488}{\htmlClass{InductiveConstructor}{\text{ChangePParams}}}}\, \\ \,\href{Ledger.Conway.Enact.html#2248}{\htmlId{3504}{\htmlClass{Generalizable}{\text{up}}}}\, \end{pmatrix}$ ,ENACT⦈
      record s { pparams = applyUpdate (PParamsOf s) up , gid }

  Enact-Wdrl : let newWdrls = s .withdrawals ∪⁺ wdrl in
    ∑[ x  newWdrls ] x  t
    ───────────────────────────────────────
    $\begin{pmatrix} \,\href{Ledger.Conway.Enact.html#2413}{\htmlId{3718}{\htmlClass{Generalizable}{\text{gid}}}}\, \\ \,\href{Ledger.Conway.Enact.html#2402}{\htmlId{3724}{\htmlClass{Generalizable}{\text{t}}}}\, \\ \,\href{Ledger.Conway.Enact.html#2433}{\htmlId{3728}{\htmlClass{Generalizable}{\text{e}}}}\, \end{pmatrix}$  s ⇀⦇ $\begin{pmatrix} \,\href{Ledger.Conway.GovernanceActions.html#933}{\htmlId{3741}{\htmlClass{InductiveConstructor}{\text{TreasuryWdrl}}}}\, \\ \,\href{Ledger.Conway.Enact.html#2378}{\htmlId{3756}{\htmlClass{Generalizable}{\text{wdrl}}}}\, \end{pmatrix}$ ,ENACT⦈ record s { withdrawals = newWdrls }

  Enact-Info :
    ───────────────────────────────────────
    $\begin{pmatrix} \,\href{Ledger.Conway.Enact.html#2413}{\htmlId{3875}{\htmlClass{Generalizable}{\text{gid}}}}\, \\ \,\href{Ledger.Conway.Enact.html#2402}{\htmlId{3881}{\htmlClass{Generalizable}{\text{t}}}}\, \\ \,\href{Ledger.Conway.Enact.html#2433}{\htmlId{3885}{\htmlClass{Generalizable}{\text{e}}}}\, \end{pmatrix}$  s ⇀⦇ $\begin{pmatrix} \,\href{Ledger.Conway.GovernanceActions.html#968}{\htmlId{3898}{\htmlClass{InductiveConstructor}{\text{Info}}}}\, \\ \,\htmlId{3905}{\htmlClass{Symbol}{\text{\_}}}\, \end{pmatrix}$ ,ENACT⦈ s