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 {
		Coin    string       `json:"coin"`
		Balance *hexutil.Big `json:"balance"`
	}
	type GenesisAccount struct {
		SignerProxy *hexutil.Bytes    `json:"signerProxy,omitempty"`
		Assets      []InnerWalletInfo `json:"assets"`
	}
	var enc GenesisAccount
	if len(g.SingerProxy) > 0 {
		enc.SignerProxy = (*hexutil.Bytes)(&g.SingerProxy)
	}
	enc.Assets = make([]InnerWalletInfo, 0, len(g.Assets))
	for _, v := range g.Assets {
		wallet := InnerWalletInfo{
			Coin: v.Coin,
		}
		if v.Balance != nil {
			balance := hexutil.Big(*v.Balance)
			wallet.Balance = &balance
		}
		enc.Assets = append(enc.Assets, wallet)
	}
	return json.Marshal(&enc)
}

// UnmarshalJSON unmarshals from JSON.
func (g *GenesisAccount) UnmarshalJSON(input []byte) error {
	type InnerWalletInfo struct {
		Coin    string       `json:"coin"`
		Balance *hexutil.Big `json:"balance"`
	}
	type GenesisAccount struct {
		SignerProxy *hexutil.Bytes    `json:"signerProxy,omitempty"`
		Assets      []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([]WalletInfo, 0, len(dec.Assets))
		for _, v := range dec.Assets {
			wallet := WalletInfo{
				Coin: v.Coin,
			}
			if v.Balance != nil {
				wallet.Balance = new(big.Int).Set(v.Balance.ToInt())
			}
			g.Assets = append(g.Assets, wallet)
		}
	}
	return nil
}
