package genesis

import (
	"encoding/json"
	"github.com/ethereum/go-ethereum/common/hexutil"
	"math/big"
)

// MarshalJSON marshals as JSON.
func (g GenesisAccount) MarshalJSON() ([]byte, error) {
	type InnerWalletInfo struct {
		Balance *hexutil.Big `json:"balance"`
		Frozen  *hexutil.Big `json:"frozen"`
	}
	type GenesisAccount struct {
		SignerProxy *hexutil.Bytes             `json:"signerProxy,omitempty"`
		Assets      map[string]InnerWalletInfo `json:"assets"`
	}
	var enc GenesisAccount
	if len(g.SingerProxy) > 0 {
		enc.SignerProxy = (*hexutil.Bytes)(&g.SingerProxy)
	}
	enc.Assets = make(map[string]InnerWalletInfo, len(g.Assets))
	for k, v := range g.Assets {
		wallet := InnerWalletInfo{}
		if v.Balance != nil {
			balance := hexutil.Big(*v.Balance)
			wallet.Balance = &balance
		}

		if v.Frozen != nil {
			frozen := hexutil.Big(*v.Frozen)
			wallet.Frozen = &frozen
		}

		enc.Assets[k] = wallet
	}
	return json.Marshal(&enc)
}

// UnmarshalJSON unmarshals from JSON.
func (g *GenesisAccount) UnmarshalJSON(input []byte) error {
	type InnerWalletInfo struct {
		Balance *hexutil.Big `json:"balance"`
		Frozen  *hexutil.Big `json:"frozen"`
	}
	type GenesisAccount struct {
		SignerProxy *hexutil.Bytes             `json:"signerProxy,omitempty"`
		Assets      map[string]InnerWalletInfo `json:"assets"`
	}
	var dec GenesisAccount
	if err := json.Unmarshal(input, &dec); err != nil {
		return err
	}
	if dec.SignerProxy != nil {
		g.SingerProxy = *dec.SignerProxy
	}

	if dec.Assets != nil {
		g.Assets = make(map[string]WalletInfo, len(dec.Assets))
		for coin, v := range dec.Assets {
			wallet := WalletInfo{}
			if v.Balance != nil {
				wallet.Balance = new(big.Int).Set(v.Balance.ToInt())
			}
			if v.Frozen != nil {
				wallet.Frozen = new(big.Int).Set(v.Frozen.ToInt())
			}
			g.Assets[coin] = wallet
		}
	}
	return nil
}
