package main

import "testing"

// TestDrawNReturnsIndependentSlice — прицельный регрессионный тест
// на реальный найденный баг: DrawN раньше возвращал подсрез самой
// колоды (out := d.cards[:n]), у которого вместимость (cap)
// простиралась до конца массива колоды. Это означало, что append к
// возвращённой "руке" писал прямо в общую с колодой (и с ранее
// розданными руками) память. Тест явно проверяет: после DrawN и
// последующего append к результату, ни оставшаяся колода, ни ранее
// выданная другая рука не должны увидеть "чужую" карту.
func TestDrawNReturnsIndependentSlice(t *testing.T) {
	d := NewDeck() // 52 карты по порядку, без перемешивания — детерминированно для теста

	hand1 := d.DrawN(5)
	hand2 := d.DrawN(5)
	hand2Before := append([]Card{}, hand2...)
	deckBefore := append([]Card{}, d.cards...)

	// имитируем "взятие карты" (append к руке первого игрока), как
	// это происходит в реальной игре при добавлении карты с добора
	hand1 = append(hand1, Card{Suit: Spades, Rank: Ace})
	_ = hand1

	for i := range d.cards {
		if d.cards[i] != deckBefore[i] {
			t.Fatalf("append к первой руке испортил оставшуюся колоду на позиции %d: было %v, стало %v",
				i, deckBefore[i], d.cards[i])
		}
	}
	for i, c := range hand2 {
		if c != hand2Before[i] {
			t.Fatalf("append к первой руке исказил вторую руку на позиции %d: было %v, стало %v",
				i, hand2Before[i], c)
		}
	}
}

// TestDrawNSequentialHandsDoNotAlias — то же самое, но раскладывает
// сразу на 4 "игроков" подряд (как при реальной раздаче в newRound)
// и проверяет, что рост ЛЮБОЙ из рук через append не портит
// остальные, ещё не выросшие руки.
func TestDrawNSequentialHandsDoNotAlias(t *testing.T) {
	d := NewDeck()
	hands := make([][]Card, 4)
	for i := range hands {
		hands[i] = d.DrawN(5)
	}

	snapshots := make([][]Card, 4)
	for i, h := range hands {
		snapshots[i] = append([]Card{}, h...)
	}

	for i := range hands {
		hands[i] = append(hands[i], Card{Suit: Hearts, Rank: Ace})
		for j := range hands {
			if j == i {
				continue
			}
			for k, c := range snapshots[j] {
				if hands[j][k] != c {
					t.Fatalf("рост руки %d испортил руку %d на позиции %d: было %v, стало %v",
						i, j, k, c, hands[j][k])
				}
			}
		}
	}
}
