module Hydra.API.ClientInput where

import Hydra.Prelude

import Hydra.Tx (ConfirmedSnapshot, IsTx (..), TxIdType)

data ClientInput tx
  = Init
  | NewTx {forall tx. ClientInput tx -> tx
transaction :: tx}
  | Recover {forall tx. ClientInput tx -> TxIdType tx
recoverTxId :: TxIdType tx}
  | Decommit {forall tx. ClientInput tx -> tx
decommitTx :: tx}
  | Close
  | SafeClose
  | Contest
  | Fanout
  | -- | Fan out a user-selected subset of the closed head's UTxO. Unlike
    -- 'Fanout' (which drains the whole set automatically), this distributes only
    -- 'utxoToFanout' and then waits for the next 'PartialFanout' command. Once a
    -- partial fanout has started, 'Fanout' is no longer accepted; the user keeps
    -- issuing 'PartialFanout' until the head is drained, at which point the node
    -- automatically produces the final fanout that burns the head tokens.
    PartialFanout {forall tx. ClientInput tx -> UTxOType tx
utxoToFanout :: UTxOType tx}
  | SideLoadSnapshot {forall tx. ClientInput tx -> ConfirmedSnapshot tx
snapshot :: ConfirmedSnapshot tx}
  deriving stock ((forall x. ClientInput tx -> Rep (ClientInput tx) x)
-> (forall x. Rep (ClientInput tx) x -> ClientInput tx)
-> Generic (ClientInput tx)
forall x. Rep (ClientInput tx) x -> ClientInput tx
forall x. ClientInput tx -> Rep (ClientInput tx) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall tx x. Rep (ClientInput tx) x -> ClientInput tx
forall tx x. ClientInput tx -> Rep (ClientInput tx) x
$cfrom :: forall tx x. ClientInput tx -> Rep (ClientInput tx) x
from :: forall x. ClientInput tx -> Rep (ClientInput tx) x
$cto :: forall tx x. Rep (ClientInput tx) x -> ClientInput tx
to :: forall x. Rep (ClientInput tx) x -> ClientInput tx
Generic)

deriving stock instance IsTx tx => Eq (ClientInput tx)
deriving stock instance IsTx tx => Show (ClientInput tx)
deriving anyclass instance IsTx tx => ToJSON (ClientInput tx)
deriving anyclass instance IsTx tx => FromJSON (ClientInput tx)

instance IsTx tx => ToCBOR (ClientInput tx) where
  toCBOR :: ClientInput tx -> Encoding
toCBOR = ClientInput tx -> Encoding
forall a. (Generic a, GToCBOR (Rep a)) => a -> Encoding
genericToCBOR

instance IsTx tx => FromCBOR (ClientInput tx) where
  fromCBOR :: forall s. Decoder s (ClientInput tx)
fromCBOR = Decoder s (ClientInput tx)
forall a s. (Generic a, GFromCBOR (Rep a)) => Decoder s a
genericFromCBOR