// Copyright 2012 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.

package build

import (
	"strconv"
	"testing"

	"golang.org/x/text/internal/colltab"
)

type entryTest struct {
	f   func(in []int) (uint32, error)
	arg []int
	val uint32
}

// makeList returns a list of entries of length n+2, with n normal
// entries plus a leading and trailing anchor.
func makeList(n int) []*entry {
	es := make([]*entry, n+2)
	weights := []rawCE{{w: []int{100, 20, 5, 0}}}
	for i := range es {
		runes := []rune{rune(i)}
		es[i] = &entry{
			runes: runes,
			elems: weights,
		}
		weights = nextWeight(colltab.Primary, weights)
	}
	for i := 1; i < len(es); i++ {
		es[i-1].next = es[i]
		es[i].prev = es[i-1]
		_, es[i-1].level = compareWeights(es[i-1].elems, es[i].elems)
	}
	es[0].exclude = true
	es[0].logical = firstAnchor
	es[len(es)-1].exclude = true
	es[len(es)-1].logical = lastAnchor
	return es
}

func TestNextIndexed(t *testing.T) {
	const n = 5
	es := makeList(n)
	for i := int64(0); i < 1<<n; i++ {
		mask := strconv.FormatInt(i+(1<<n), 2)
		for i, c := range mask {
			es[i].exclude = c == '1'
		}
		e := es[0]
		for i, c := range mask {
			if c == '0' {
				e, _ = e.nextIndexed()
				if e != es[i] {
					t.Errorf("%d: expected entry %d; found %d", i, es[i].elems, e.elems)
				}
			}
		}
		if e, _ = e.nextIndexed(); e != nil {
			t.Errorf("%d: expected nil entry; found %d", i, e.elems)
		}
	}
}

func TestRemove(t *testing.T) {
	const n = 5
	for i := int64(0); i < 1<<n; i++ {
		es := makeList(n)
		mask := strconv.FormatInt(i+(1<<n), 2)
		for i, c := range mask {
			if c == '0' {
				es[i].remove()
			}
		}
		e := es[0]
		for i, c := range mask {
			if c == '1' {
				if e != es[i] {
					t.Errorf("%d: expected entry %d; found %d", i, es[i].elems, e.elems)
				}
				e, _ = e.nextIndexed()
			}
		}
		if e != nil {
			t.Errorf("%d: expected nil entry; found %d", i, e.elems)
		}
	}
}

// nextPerm generates the next permutation of the array.  The starting
// permutation is assumed to be a list of integers sorted in increasing order.
// It returns false if there are no more permutations left.
func nextPerm(a []int) bool {
	i := len(a) - 2
	for ; i >= 0; i-- {
		if a[i] < a[i+1] {
			break
		}
	}
	if i < 0 {
		return false
	}
	for j := len(a) - 1; j >= i; j-- {
		if a[j] > a[i] {
			a[i], a[j] = a[j], a[i]
			break
		}
	}
	for j := i + 1; j < (len(a)+i+1)/2; j++ {
		a[j], a[len(a)+i-j] = a[len(a)+i-j], a[j]
	}
	return true
}

func TestInsertAfter(t *testing.T) {
	const n = 5
	orig := makeList(n)
	perm := make([]int, n)
	for i := range perm {
		perm[i] = i + 1
	}
	for ok := true; ok; ok = nextPerm(perm) {
		es := makeList(n)
		last := es[0]
		for _, i := range perm {
			last.insertAfter(es[i])
			last = es[i]
		}
		for _, e := range es {
			e.elems = es[0].elems
		}
		e := es[0]
		for _, i := range perm {
			e, _ = e.nextIndexed()
			if e.runes[0] != orig[i].runes[0] {
				t.Errorf("%d:%d: expected entry %X; found %X", perm, i, orig[i].runes, e.runes)
				break
			}
		}
	}
}

func TestInsertBefore(t *testing.T) {
	const n = 5
	orig := makeList(n)
	perm := make([]int, n)
	for i := range perm {
		perm[i] = i + 1
	}
	for ok := true; ok; ok = nextPerm(perm) {
		es := makeList(n)
		last := es[len(es)-1]
		for _, i := range perm {
			last.insertBefore(es[i])
			last = es[i]
		}
		for _, e := range es {
			e.elems = es[0].elems
		}
		e := es[0]
		for i := n - 1; i >= 0; i-- {
			e, _ = e.nextIndexed()
			if e.runes[0] != rune(perm[i]) {
				t.Errorf("%d:%d: expected entry %X; found %X", perm, i, orig[i].runes, e.runes)
				break
			}
		}
	}
}

type entryLessTest struct {
	a, b *entry
	res  bool
}

var (
	w1 = []rawCE{{w: []int{100, 20, 5, 5}}}
	w2 = []rawCE{{w: []int{101, 20, 5, 5}}}
)

var entryLessTests = []entryLessTest{
	{&entry{str: "a", elems: w1},
		&entry{str: "a", elems: w1},
		false,
	},
	{&entry{str: "a", elems: w1},
		&entry{str: "a", elems: w2},
		true,
	},
	{&entry{str: "a", elems: w1},
		&entry{str: "b", elems: w1},
		true,
	},
	{&entry{str: "a", elems: w2},
		&entry{str: "a", elems: w1},
		false,
	},
	{&entry{str: "c", elems: w1},
		&entry{str: "b", elems: w1},
		false,
	},
	{&entry{str: "a", elems: w1, logical: firstAnchor},
		&entry{str: "a", elems: w1},
		true,
	},
	{&entry{str: "a", elems: w1},
		&entry{str: "b", elems: w1, logical: firstAnchor},
		false,
	},
	{&entry{str: "b", elems: w1},
		&entry{str: "a", elems: w1, logical: lastAnchor},
		true,
	},
	{&entry{str: "a", elems: w1, logical: lastAnchor},
		&entry{str: "c", elems: w1},
		false,
	},
}

func TestEntryLess(t *testing.T) {
	for i, tt := range entryLessTests {
		if res := entryLess(tt.a, tt.b); res != tt.res {
			t.Errorf("%d: was %v; want %v", i, res, tt.res)
		}
	}
}
