package world

import (
	"reflect"
	"testing"
)

func TestPlacedOresUseStoneAndDeepslateTargets(t *testing.T) {
	gen := NewVanillaGenerator(12345)
	want := map[uint16]string{
		131:  "iron ore",
		132:  "deepslate iron ore",
		5307: "diamond ore",
		5308: "deepslate diamond ore",
	}
	counts := make(map[uint16]int)
	for _, pos := range [][2]int32{{-8, -8}, {4, -4}} {
		chunk := gen(pos[0], pos[1])
		for y := MinY; y < 128; y++ {
			for x := 0; x < 16; x++ {
				for z := 0; z < 16; z++ {
					counts[chunk.GetBlock(x, y, z)]++
				}
			}
		}
	}
	for state, name := range want {
		if counts[state] == 0 {
			t.Errorf("no %s generated by placed ore features", name)
		}
	}
}

func TestPlacedOresAreDeterministic(t *testing.T) {
	gen := NewVanillaGenerator(4242)
	a, b := gen(3, -2), gen(3, -2)
	for y := MinY; y < MinY+WorldHeight; y++ {
		for x := 0; x < 16; x++ {
			for z := 0; z < 16; z++ {
				if got, want := a.GetBlock(x, y, z), b.GetBlock(x, y, z); got != want {
					t.Fatalf("block (%d,%d,%d): first %d second %d", x, y, z, got, want)
				}
			}
		}
	}
}

func TestWalkOreBlocksUsesVanillaSphereOrder(t *testing.T) {
	spheres := []oreSphere{
		{x: 0.5, y: 0.5, z: 0.5, radius: 1.1},
		{x: 1.5, y: 0.5, z: 0.5, radius: 1.1},
	}
	var got [][3]int
	walkOreBlocks(spheres, func(x, y, z int) {
		got = append(got, [3]int{x, y, z})
	})
	want := [][3]int{
		{-1, 0, 0},
		{0, -1, 0}, {0, 0, -1}, {0, 0, 0}, {0, 0, 1}, {0, 1, 0},
		{1, 0, 0},
		{1, -1, 0}, {1, 0, -1}, {1, 0, 1}, {1, 1, 0},
		{2, 0, 0},
	}
	if !reflect.DeepEqual(got, want) {
		t.Fatalf("walkOreBlocks = %v, want %v", got, want)
	}
}
