{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# OPTIONS_GHC -Wno-orphans #-}

module Cardano.Ledger.Orphans where

import Cardano.Crypto.Hash (Hash (..))
import qualified Cardano.Crypto.Hash as Hash
import qualified Cardano.Crypto.Hash.Class as HS
import Cardano.Crypto.Util (SignableRepresentation (..))
import qualified Cardano.Crypto.Wallet as WC
import Control.DeepSeq (NFData)
import Data.Aeson
import qualified Data.ByteString as Long (ByteString, empty)
import qualified Data.ByteString.Lazy as Lazy (ByteString, empty)
import qualified Data.ByteString.Short as Short (ShortByteString, empty, pack)
import Data.Default (Default (..))
import Data.Fixed (Fixed (..))
import Data.IP (IPv4, IPv6)
import Data.Proxy
import qualified Data.Sequence.Strict as SS
import qualified Data.Text as Text
import NoThunks.Class (NoThunks (..))
import Text.Read (readEither)

instance FromJSON IPv4 where
  parseJSON :: Value -> Parser IPv4
parseJSON =
    forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText String
"IPv4" forall a b. (a -> b) -> a -> b
$ \Text
txt -> case forall a. Read a => String -> Either String a
readEither (Text -> String
Text.unpack Text
txt) of
      Right IPv4
ipv4 -> forall (m :: * -> *) a. Monad m => a -> m a
return IPv4
ipv4
      Left String
_ -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"failed to read as IPv4 " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Text
txt

instance ToJSON IPv4 where
  toJSON :: IPv4 -> Value
toJSON = forall a. ToJSON a => a -> Value
toJSON forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show

instance FromJSON IPv6 where
  parseJSON :: Value -> Parser IPv6
parseJSON =
    forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText String
"IPv6" forall a b. (a -> b) -> a -> b
$ \Text
txt -> case forall a. Read a => String -> Either String a
readEither (Text -> String
Text.unpack Text
txt) of
      Right IPv6
ipv6 -> forall (m :: * -> *) a. Monad m => a -> m a
return IPv6
ipv6
      Left String
_ -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"failed to read as IPv6 " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Text
txt

instance ToJSON IPv6 where
  toJSON :: IPv6 -> Value
toJSON = forall a. ToJSON a => a -> Value
toJSON forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show

instance NoThunks IPv4

instance NoThunks IPv6

instance NFData IPv4

instance NFData IPv6

instance NoThunks WC.XSignature where
  wNoThunks :: Context -> XSignature -> IO (Maybe ThunkInfo)
wNoThunks Context
ctxt XSignature
s = forall a. NoThunks a => Context -> a -> IO (Maybe ThunkInfo)
wNoThunks Context
ctxt (XSignature -> ByteString
WC.unXSignature XSignature
s)
  showTypeOf :: Proxy XSignature -> String
showTypeOf Proxy XSignature
_proxy = String
"XSignature"

instance SignableRepresentation (Hash.Hash a b) where
  getSignableRepresentation :: Hash a b -> ByteString
getSignableRepresentation = forall a b. Hash a b -> ByteString
Hash.hashToBytes

-- | TODO: We should upstream instance
-- HasResolution p => NoThunks (Fixed p) into the nothunks package.
deriving newtype instance NoThunks (Fixed p)

-- ===============================================
-- Blank instance needed to compute Provenance

instance Default (SS.StrictSeq t) where
  def :: StrictSeq t
def = forall t. StrictSeq t
SS.Empty

instance Default Short.ShortByteString where
  def :: ShortByteString
def = ShortByteString
Short.empty

instance Default Long.ByteString where
  def :: ByteString
def = ByteString
Long.empty

instance Default Lazy.ByteString where
  def :: ByteString
def = ByteString
Lazy.empty

instance HS.HashAlgorithm h => Default (Hash h b) where
  def :: Hash h b
def =
    forall h a. HashAlgorithm h => ShortByteString -> Hash h a
UnsafeHash forall a b. (a -> b) -> a -> b
$
      [Word8] -> ShortByteString
Short.pack forall a b. (a -> b) -> a -> b
$
        forall a. Int -> a -> [a]
replicate (forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall h (proxy :: * -> *). HashAlgorithm h => proxy h -> Word
Hash.sizeHash (forall {k} (t :: k). Proxy t
Proxy :: Proxy h))) Word8
0