{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE OverloadedStrings #-}

module Cardano.Chain.Update.InstallerHash
  ( InstallerHash (..),
  )
where

import Cardano.Binary
  ( FromCBOR (..),
    Raw,
    ToCBOR (..),
    dropBytes,
    encodeListLen,
    enforceSize,
  )
import Cardano.Crypto (Hash, hashRaw)
import Cardano.Prelude
import Data.Aeson (ToJSON)
import Formatting (bprint, build)
import qualified Formatting.Buildable as B
import NoThunks.Class (NoThunks (..))

-- | The hash of the installer of the new application
newtype InstallerHash = InstallerHash
  { InstallerHash -> Hash Raw
unInstallerHash :: Hash Raw
  }
  deriving (InstallerHash -> InstallerHash -> Bool
(InstallerHash -> InstallerHash -> Bool)
-> (InstallerHash -> InstallerHash -> Bool) -> Eq InstallerHash
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: InstallerHash -> InstallerHash -> Bool
$c/= :: InstallerHash -> InstallerHash -> Bool
== :: InstallerHash -> InstallerHash -> Bool
$c== :: InstallerHash -> InstallerHash -> Bool
Eq, Int -> InstallerHash -> ShowS
[InstallerHash] -> ShowS
InstallerHash -> String
(Int -> InstallerHash -> ShowS)
-> (InstallerHash -> String)
-> ([InstallerHash] -> ShowS)
-> Show InstallerHash
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [InstallerHash] -> ShowS
$cshowList :: [InstallerHash] -> ShowS
show :: InstallerHash -> String
$cshow :: InstallerHash -> String
showsPrec :: Int -> InstallerHash -> ShowS
$cshowsPrec :: Int -> InstallerHash -> ShowS
Show, (forall x. InstallerHash -> Rep InstallerHash x)
-> (forall x. Rep InstallerHash x -> InstallerHash)
-> Generic InstallerHash
forall x. Rep InstallerHash x -> InstallerHash
forall x. InstallerHash -> Rep InstallerHash x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep InstallerHash x -> InstallerHash
$cfrom :: forall x. InstallerHash -> Rep InstallerHash x
Generic)
  deriving anyclass (InstallerHash -> ()
(InstallerHash -> ()) -> NFData InstallerHash
forall a. (a -> ()) -> NFData a
rnf :: InstallerHash -> ()
$crnf :: InstallerHash -> ()
NFData, Context -> InstallerHash -> IO (Maybe ThunkInfo)
Proxy InstallerHash -> String
(Context -> InstallerHash -> IO (Maybe ThunkInfo))
-> (Context -> InstallerHash -> IO (Maybe ThunkInfo))
-> (Proxy InstallerHash -> String)
-> NoThunks InstallerHash
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
showTypeOf :: Proxy InstallerHash -> String
$cshowTypeOf :: Proxy InstallerHash -> String
wNoThunks :: Context -> InstallerHash -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> InstallerHash -> IO (Maybe ThunkInfo)
noThunks :: Context -> InstallerHash -> IO (Maybe ThunkInfo)
$cnoThunks :: Context -> InstallerHash -> IO (Maybe ThunkInfo)
NoThunks)

instance B.Buildable InstallerHash where
  build :: InstallerHash -> Builder
build (InstallerHash Hash Raw
h) = Format Builder (Hash Raw -> Builder) -> Hash Raw -> Builder
forall a. Format Builder a -> a
bprint (Format (Hash Raw -> Builder) (Hash Raw -> Builder)
"{ installer hash: " Format (Hash Raw -> Builder) (Hash Raw -> Builder)
-> Format Builder (Hash Raw -> Builder)
-> Format Builder (Hash Raw -> Builder)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Format Builder (Hash Raw -> Builder)
forall a r. Buildable a => Format r (a -> r)
build Format Builder (Hash Raw -> Builder)
-> Format Builder Builder -> Format Builder (Hash Raw -> Builder)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Format Builder Builder
" }") Hash Raw
h

-- Used for debugging purposes only
instance ToJSON InstallerHash

instance ToCBOR InstallerHash where
  toCBOR :: InstallerHash -> Encoding
toCBOR (InstallerHash Hash Raw
h) =
    Word -> Encoding
encodeListLen Word
4
      Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> Hash Raw -> Encoding
forall a. ToCBOR a => a -> Encoding
toCBOR Hash Raw
emptyHash
      Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> Hash Raw -> Encoding
forall a. ToCBOR a => a -> Encoding
toCBOR Hash Raw
h
      Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> Hash Raw -> Encoding
forall a. ToCBOR a => a -> Encoding
toCBOR Hash Raw
emptyHash
      Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> Hash Raw -> Encoding
forall a. ToCBOR a => a -> Encoding
toCBOR Hash Raw
emptyHash
    where
      emptyHash :: Hash Raw
emptyHash = ByteString -> Hash Raw
hashRaw ByteString
"\NUL"

instance FromCBOR InstallerHash where
  fromCBOR :: Decoder s InstallerHash
fromCBOR = do
    Text -> Int -> Decoder s ()
forall s. Text -> Int -> Decoder s ()
enforceSize Text
"InstallerHash" Int
4
    Decoder s ()
forall s. Dropper s
dropBytes
    Hash Raw
h <- Decoder s (Hash Raw)
forall a s. FromCBOR a => Decoder s a
fromCBOR
    Decoder s ()
forall s. Dropper s
dropBytes
    Decoder s ()
forall s. Dropper s
dropBytes
    InstallerHash -> Decoder s InstallerHash
forall (f :: * -> *) a. Applicative f => a -> f a
pure (InstallerHash -> Decoder s InstallerHash)
-> InstallerHash -> Decoder s InstallerHash
forall a b. (a -> b) -> a -> b
$ Hash Raw -> InstallerHash
InstallerHash Hash Raw
h