{-# LANGUAGE DeriveDataTypeable         #-}
{-# LANGUAGE DeriveGeneric              #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings          #-}
{-# LANGUAGE TemplateHaskell            #-}
module Network.Polkadot.Api.Types where
import           Data.Aeson               (FromJSON (..),
                                           Options (fieldLabelModifier),
                                           ToJSON (..), Value (String),
                                           defaultOptions)
import           Data.Aeson.TH            (deriveJSON)
import           Data.Text                (Text)
import           Data.Word                (Word32, Word64, Word8)
import           GHC.Generics             (Generic)
import           Data.ByteArray.HexString (HexString)
import           Data.String.Extra        (toLowerFirst)
data NodeRole = Full
    | LightClient
    | Authority
    | Sentry
    deriving (Eq, Generic, Show)
$(deriveJSON defaultOptions ''NodeRole)
data ChainType = Development
    | Local
    | Live
    | Custom Text
    deriving (Eq, Generic, Show)
instance FromJSON ChainType where
    parseJSON (String v) = return $ case v of
        "Development" -> Development
        "Local"       -> Local
        "Live"        -> Live
        custom_name   -> Custom custom_name
    parseJSON _ = fail "ChainType should be a JSON String"
instance ToJSON ChainType where
    toJSON (Custom v) = toJSON v
    toJSON v          = toJSON (show v)
data Health = Health
    { healthPeers           :: Int
    
    , healthIsSyncing       :: Bool
    
    , healthShouldHavePeers :: Bool
    
    }
    deriving (Eq, Generic, Show)
$(deriveJSON (defaultOptions
    { fieldLabelModifier = toLowerFirst . drop 6 }) ''Health)
data PeerInfo = PeerInfo
    { peerInfoPeerId          :: Text
    
    , peerInfoRoles           :: [NodeRole]
    
    , peerInfoProtocolVersion :: Int
    
    , peerInfoBestHash        :: Text
    
    , peerInfoBestNumber      :: Int
    
    }
    deriving (Eq, Generic, Show)
$(deriveJSON (defaultOptions
    { fieldLabelModifier = toLowerFirst . drop 8 }) ''PeerInfo)
data ContractCall = ContractCall
    { callOrigin    :: HexString
    , callDest      :: HexString
    , callValue     :: Integer
    , callGasLimit  :: Integer
    , callInputData :: HexString
    }
    deriving (Eq, Generic, Show)
$(deriveJSON (defaultOptions
    { fieldLabelModifier = toLowerFirst . drop 4 }) ''ContractCall)
data ContractExecResult = SuccessExec
    { execStatus :: Word8
    
    , execData   :: Maybe HexString
    
    }
    | ExecResultError
    deriving (Eq, Generic, Show)
$(deriveJSON (defaultOptions
    { fieldLabelModifier = toLowerFirst . drop 4 }) ''ContractExecResult)
type Metadata = Value
data ReadProof = ReadProof
    { readProofAt    :: HexString
    
    , readProofProof :: [HexString]
    
    }
    deriving (Eq, Generic, Show)
$(deriveJSON (defaultOptions
    { fieldLabelModifier = toLowerFirst . drop 9 }) ''ReadProof)
data RuntimeVersion = RuntimeVersion
    { runtimeSpecName           :: Text
    
    , runtimeImplName           :: Text
    
    , runtimeAuthoringVersion   :: Word32
    
    , runtimeSpecVersion        :: Word32
    
    , runtimeImplVersion        :: Word32
    
    , runtimeApis               :: [(HexString, Word32)]
    
    , runtimeTransactionVersion :: Word32
    
    }
    deriving (Eq, Generic, Show)
$(deriveJSON (defaultOptions
    { fieldLabelModifier = toLowerFirst . drop 7 }) ''RuntimeVersion)
type StorageKind = Word8
data StorageChangeSet = StorageChangeSet
    { storageBlock   :: HexString
    
    , storageChanges :: [(HexString, Maybe HexString)]
    
    }
$(deriveJSON (defaultOptions
    { fieldLabelModifier = toLowerFirst . drop 7 }) ''StorageChangeSet)
type Weight = Word64
data DispatchClass = Normal
    | Operational
    | Mandatory
    deriving (Eq, Generic, Show)
$(deriveJSON defaultOptions ''DispatchClass)
data RuntimeDispatchInfo = RuntimeDispatchInfo
    { dispatchWeight     :: Weight
    
    , dispatchClass      :: DispatchClass
    
    , dispatchPartialFee :: Integer
    
    }
    deriving (Eq, Generic, Show)
$(deriveJSON (defaultOptions
    { fieldLabelModifier = toLowerFirst . drop 8 }) ''RuntimeDispatchInfo)
data ImportedAux = ImportedAux
    { auxHeaderOnly                 :: Bool
    
    , auxClearJustificationRequests :: Bool
    
    , auxNeedsJustification         :: Bool
    
    , auxBadJustification           :: Bool
    
    , auxNeedsFinalityProof         :: Bool
    
    , auxIsNewBest                  :: Bool
    
    }
    deriving (Eq, Generic, Show)
$(deriveJSON (defaultOptions
    { fieldLabelModifier = toLowerFirst . drop 3 }) ''ImportedAux)
data CreatedBlock = CreatedBlock
    { createdBlockHash :: HexString
    , createdBlockAux  :: ImportedAux
    }
    deriving (Eq, Generic, Show)
$(deriveJSON (defaultOptions
    { fieldLabelModifier = toLowerFirst . drop 12 }) ''CreatedBlock)
data Header = Header
    { headerParentHash     :: HexString
    
    , headerNumber         :: Int
    
    , headerStateRoot      :: HexString
    
    , headerExtrinsicsRoot :: HexString
    
    , headerDigest         :: HexString
    
    }
    deriving (Eq, Generic, Show)
$(deriveJSON (defaultOptions
    { fieldLabelModifier = toLowerFirst . drop 5 }) ''Header)
data Block = Block
    { blockHeader     :: Header
    
    , blockExtrinsics :: [HexString]
    
    }
    deriving (Eq, Generic, Show)
$(deriveJSON (defaultOptions
    { fieldLabelModifier = toLowerFirst . drop 5 }) ''Block)
data SignedBlock = SignedBlock
    { signedBlock         :: Block
    
    , signedJustification :: Maybe HexString
    
    }
    deriving (Eq, Generic, Show)
$(deriveJSON (defaultOptions
    { fieldLabelModifier = toLowerFirst . drop 6 }) ''SignedBlock)