package gmath

import (
	"math/big"
)

// BigIntx is a big.Int of x
var (
	BigInt0    = big.NewInt(0)
	BigInt1    = big.NewInt(1)
	BigInt2    = big.NewInt(2)
	BigInt3    = big.NewInt(3)
	BigInt4    = big.NewInt(4)
	BigInt5    = big.NewInt(5)
	BigInt6    = big.NewInt(6)
	BigInt7    = big.NewInt(7)
	BigInt8    = big.NewInt(8)
	BigInt9    = big.NewInt(9)
	BigInt10   = big.NewInt(10)
	BigInt11   = big.NewInt(11)
	BigInt12   = big.NewInt(12)
	BigInt2256 = new(big.Int).Lsh(BigInt1, 256) // = 2^256
)

// IsBigInt0 return if x==0
func IsBigInt0(x *big.Int) bool {
	return x.Sign() == 0
}

// IsBigInt1 return if x==0
func IsBigInt1(x *big.Int) bool {
	return x.Cmp(BigInt1) == 0
}

// ClearBigInt set memory of x be 0
func ClearBigInt(x *big.Int) {
	if x == nil {
		return
	}
	words := x.Bits()
	for i := range words {
		words[i] = 0
	}
	x.SetInt64(0)
}

type bytes interface {
	Bytes() []byte
}

// ToNBytes ouput a bytes to fix n bytes. extend as 0.
func ToNBytes(b bytes, n int) []byte {
	abs := b.Bytes()
	l := len(abs)
	var s []byte
	// l==n is the most case (255/256)
	if l >= n {
		s = abs[l-n : l]
	} else {
		s = make([]byte, n)
		copy(s[n-l:], abs)
	}
	return s
}

// BigIntToNByte return a n byte slice of the input big.Int as big-endian
// if len(a.Bytes()) > n, then only the lower n bytes are return
func BigIntToNByte(a *big.Int, n int) []byte {
	return ToNBytes(a, n)
}
