//go:build gmp
// +build gmp

package gmp

/*
#cgo LDFLAGS: -lgmp
#include <gmp.h>
#include <stdlib.h>
*/
import "C"
import (
	"math/big"
)

const MaxBase = 62

// itoa is like utoa but it prepends a '-' if neg && x != 0.
func itoa(x []byte, neg bool, base int) string {
	if base < 2 || base > MaxBase {
		panic("invalid base")
	}

	// x == 0
	if len(x) == 0 {
		return "0"
	}
	// len(x) > 0

	n := new(big.Int).SetBytes(x)
	if neg {
		n.Neg(n)
	}
	return n.Text(base)

}

// Text returns the string representation of x in the given base.
// Base must be between 2 and 62, inclusive. The result uses the
// lower-case letters 'a' to 'z' for digit values 10 to 35, and
// the upper-case letters 'A' to 'Z' for digit values 36 to 61.
// No prefix (such as "0x") is added to the string. If x is a nil
// pointer it returns "<nil>".
func (x *Int) Text(base int) string {
	if x == nil {
		return "<nil>"
	}
	nat := x.Bytes()

	return string(itoa(nat, x.Sign() < 0, base))
}

// Bits return the bits of x
func (x *Int) Bits() uint {
	// return uint(C.mpz_bitcnt(x.i))
	panic("unimplement")
}

// ToNBytes ouput a bytes to fix n bytes. extend as 0.
func toNBytes(b *Int, 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
}

func (x *Int) FillBytes(b []byte) []byte {
	bb := toNBytes(x, len(b))
	copy(b, bb)
	return b
}
