package board_test

import (
	"testing"

	"github.com/iliadenisov/alphabet"

	"gitea.iliadenisov.ru/developer/scrabble-solver/board"
	"gitea.iliadenisov.ru/developer/scrabble-solver/internal/encoding"
)

func TestParseAndAccess(t *testing.T) {
	b, err := board.Parse([]string{
		"cat",
		"o..",
		"W..", // blank standing for 'w'
	}, alphabet.Latin())
	if err != nil {
		t.Fatal(err)
	}
	if b.Rows() != 3 || b.Cols() != 3 {
		t.Fatalf("size = %dx%d, want 3x3", b.Rows(), b.Cols())
	}
	if b.IsEmpty() {
		t.Error("IsEmpty = true for a non-empty board")
	}
	if !b.Empty(1, 1) {
		t.Error("(1,1) should be empty")
	}
	if !b.Filled(0, 0) {
		t.Error("(0,0) should be filled")
	}

	// 'c' = index 2, normal tile.
	if got := b.At(0, 0); got != encoding.Cell(2, false) {
		t.Errorf("At(0,0) = %#x, want %#x", got, encoding.Cell(2, false))
	}
	if encoding.IsBlank(b.At(0, 0)) {
		t.Error("(0,0) wrongly marked blank")
	}
	// 'W' = blank for index 22.
	if got := b.At(2, 0); got != encoding.Cell(22, true) {
		t.Errorf("At(2,0) = %#x, want blank w", got)
	}
	if !encoding.IsBlank(b.At(2, 0)) {
		t.Error("(2,0) should be a blank")
	}
}

func TestNewIsEmpty(t *testing.T) {
	if !board.New(15, 15).IsEmpty() {
		t.Error("new board not empty")
	}
}

func TestTranspose(t *testing.T) {
	b, _ := board.Parse([]string{
		"ab",
		"..",
		"cd",
	}, alphabet.Latin())
	tr := b.Transpose()
	if tr.Rows() != 2 || tr.Cols() != 3 {
		t.Fatalf("transpose size = %dx%d, want 2x3", tr.Rows(), tr.Cols())
	}
	if tr.At(0, 0) != b.At(0, 0) || tr.At(1, 0) != b.At(0, 1) || tr.At(0, 2) != b.At(2, 0) {
		t.Error("transpose did not swap coordinates")
	}

	// Transposing twice restores the original.
	back := tr.Transpose()
	for r := range b.Rows() {
		for c := range b.Cols() {
			if back.At(r, c) != b.At(r, c) {
				t.Fatalf("double transpose differs at (%d,%d)", r, c)
			}
		}
	}
}

func TestClone(t *testing.T) {
	b := board.New(3, 3)
	b.Set(1, 1, encoding.Cell(0, false))
	cp := b.Clone()
	cp.Set(0, 0, encoding.Cell(1, false))
	if !b.Empty(0, 0) {
		t.Error("mutating clone changed the original")
	}
	if cp.Empty(1, 1) {
		t.Error("clone lost original content")
	}
}
