// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file implements the Bits type used for testing Float operations
// via an independent (albeit slower) representations for floating-point
// numbers.

package big

import (
	"fmt"
	"slices"
	"testing"
)

// A Bits value b represents a finite floating-point number x of the form
//
//	x = 2**b[0] + 2**b[1] + ... 2**b[len(b)-1]
//
// The order of slice elements is not significant. Negative elements may be
// used to form fractions. A Bits value is normalized if each b[i] occurs at
// most once. For instance Bits{0, 0, 1} is not normalized but represents the
// same floating-point number as Bits{2}, which is normalized. The zero (nil)
// value of Bits is a ready to use Bits value and represents the value 0.
type Bits []int

func (x Bits) add(y Bits) Bits {
	return append(x, y...)
}

func (x Bits) mul(y Bits) Bits {
	var p Bits
	for _, x := range x {
		for _, y := range y {
			p = append(p, x+y)
		}
	}
	return p
}

func TestMulBits(t *testing.T) {
	for _, test := range []struct {
		x, y, want Bits
	}{
		{nil, nil, nil},
		{Bits{}, Bits{}, nil},
		{Bits{0}, Bits{0}, Bits{0}},
		{Bits{0}, Bits{1}, Bits{1}},
		{Bits{1}, Bits{1, 2, 3}, Bits{2, 3, 4}},
		{Bits{-1}, Bits{1}, Bits{0}},
		{Bits{-10, -1, 0, 1, 10}, Bits{1, 2, 3}, Bits{-9, -8, -7, 0, 1, 2, 1, 2, 3, 2, 3, 4, 11, 12, 13}},
	} {
		got := fmt.Sprintf("%v", test.x.mul(test.y))
		want := fmt.Sprintf("%v", test.want)
		if got != want {
			t.Errorf("%v * %v = %s; want %s", test.x, test.y, got, want)
		}

	}
}

// norm returns the normalized bits for x: It removes multiple equal entries
// by treating them as an addition (e.g., Bits{5, 5} => Bits{6}), and it sorts
// the result list for reproducible results.
func (x Bits) norm() Bits {
	m := make(map[int]bool)
	for _, b := range x {
		for m[b] {
			m[b] = false
			b++
		}
		m[b] = true
	}
	var z Bits
	for b, set := range m {
		if set {
			z = append(z, b)
		}
	}
	slices.Sort([]int(z))
	return z
}

func TestNormBits(t *testing.T) {
	for _, test := range []struct {
		x, want Bits
	}{
		{nil, nil},
		{Bits{}, Bits{}},
		{Bits{0}, Bits{0}},
		{Bits{0, 0}, Bits{1}},
		{Bits{3, 1, 1}, Bits{2, 3}},
		{Bits{10, 9, 8, 7, 6, 6}, Bits{11}},
	} {
		got := fmt.Sprintf("%v", test.x.norm())
		want := fmt.Sprintf("%v", test.want)
		if got != want {
			t.Errorf("normBits(%v) = %s; want %s", test.x, got, want)
		}

	}
}

// round returns the Float value corresponding to x after rounding x
// to prec bits according to mode.
func (x Bits) round(prec uint, mode RoundingMode) *Float {
	x = x.norm()

	// determine range
	var min, max int
	for i, b := range x {
		if i == 0 || b < min {
			min = b
		}
		if i == 0 || b > max {
			max = b
		}
	}
	prec0 := uint(max + 1 - min)
	if prec >= prec0 {
		return x.Float()
	}
	// prec < prec0

	// determine bit 0, rounding, and sticky bit, and result bits z
	var bit0, rbit, sbit uint
	var z Bits
	r := max - int(prec)
	for _, b := range x {
		switch {
		case b == r:
			rbit = 1
		case b < r:
			sbit = 1
		default:
			// b > r
			if b == r+1 {
				bit0 = 1
			}
			z = append(z, b)
		}
	}

	// round
	f := z.Float() // rounded to zero
	if mode == ToNearestAway {
		panic("not yet implemented")
	}
	if mode == ToNearestEven && rbit == 1 && (sbit == 1 || sbit == 0 && bit0 != 0) || mode == AwayFromZero {
		// round away from zero
		f.SetMode(ToZero).SetPrec(prec)
		f.Add(f, Bits{int(r) + 1}.Float())
	}
	return f
}

// Float returns the *Float z of the smallest possible precision such that
// z = sum(2**bits[i]), with i = range bits. If multiple bits[i] are equal,
// they are added: Bits{0, 1, 0}.Float() == 2**0 + 2**1 + 2**0 = 4.
func (bits Bits) Float() *Float {
	// handle 0
	if len(bits) == 0 {
		return new(Float)
	}
	// len(bits) > 0

	// determine lsb exponent
	var min int
	for i, b := range bits {
		if i == 0 || b < min {
			min = b
		}
	}

	// create bit pattern
	x := NewInt(0)
	for _, b := range bits {
		badj := b - min
		// propagate carry if necessary
		for x.Bit(badj) != 0 {
			x.SetBit(x, badj, 0)
			badj++
		}
		x.SetBit(x, badj, 1)
	}

	// create corresponding float
	z := new(Float).SetInt(x) // normalized
	if e := int64(z.exp) + int64(min); MinExp <= e && e <= MaxExp {
		z.exp = int32(e)
	} else {
		// this should never happen for our test cases
		panic("exponent out of range")
	}
	return z
}

func TestFromBits(t *testing.T) {
	for _, test := range []struct {
		bits Bits
		want string
	}{
		// all different bit numbers
		{nil, "0"},
		{Bits{0}, "0x.8p+1"},
		{Bits{1}, "0x.8p+2"},
		{Bits{-1}, "0x.8p+0"},
		{Bits{63}, "0x.8p+64"},
		{Bits{33, -30}, "0x.8000000000000001p+34"},
		{Bits{255, 0}, "0x.8000000000000000000000000000000000000000000000000000000000000001p+256"},

		// multiple equal bit numbers
		{Bits{0, 0}, "0x.8p+2"},
		{Bits{0, 0, 0, 0}, "0x.8p+3"},
		{Bits{0, 1, 0}, "0x.8p+3"},
		{append(Bits{2, 1, 0} /* 7 */, Bits{3, 1} /* 10 */ ...), "0x.88p+5" /* 17 */},
	} {
		f := test.bits.Float()
		if got := f.Text('p', 0); got != test.want {
			t.Errorf("setBits(%v) = %s; want %s", test.bits, got, test.want)
		}
	}
}
