package main

import (
	"fmt"
	"testing"
)

func TestAlgorithm(t *testing.T) {
	tests := []struct {
		grid         [][]rune
		expectedGrid [][]rune
	}{
		{
			grid: [][]rune{
				[]rune{'.', '#', '.', '.', '#'},
				[]rune{'.', '.', '.', '.', '.'},
				[]rune{'#', '#', '#', '#', '#'},
				[]rune{'.', '.', '.', '.', '#'},
				[]rune{'.', '.', '.', '#', '#'},
			},
			expectedGrid: [][]rune{
				[]rune{'.', '7', '.', '.', '7'},
				[]rune{'.', '.', '.', '.', '.'},
				[]rune{'6', '7', '7', '7', '5'},
				[]rune{'.', '.', '.', '.', '7'},
				[]rune{'.', '.', '.', '8', '7'},
			},
		},
	}

	for _, test := range tests {
		FindBestPosition(test.grid, true)
		fmt.Println("Got:")
		for y := range test.grid {
			for x := range test.grid[y] {
				if test.grid[y][x] == '.' {
					fmt.Printf(".")
				} else {
					fmt.Printf("%d", test.grid[y][x])
				}
			}
			fmt.Println()
		}
		fmt.Println("Expected:")
		for y := range test.expectedGrid {
			for x := range test.expectedGrid[y] {
				fmt.Printf("%c", test.expectedGrid[y][x])
			}
			fmt.Println()
		}
		fmt.Println()
	}
}

func TestFindPosition(t *testing.T) {
	tests := []struct {
		grid     [][]rune
		expected Point
	}{
		{
			grid: [][]rune{
				[]rune{'.', '#', '.', '.', '#'},
				[]rune{'.', '.', '.', '.', '.'},
				[]rune{'#', '#', '#', '#', '#'},
				[]rune{'.', '.', '.', '.', '#'},
				[]rune{'.', '.', '.', '#', '#'},
			},
			expected: Point{x: 3, y: 4},
		},
		{
			grid: [][]rune{
				[]rune{'.', '.', '.', '.', '.', '.', '#', '.', '#', '.'},
				[]rune{'#', '.', '.', '#', '.', '#', '.', '.', '.', '.'},
				[]rune{'.', '.', '#', '#', '#', '#', '#', '#', '#', '.'},
				[]rune{'.', '#', '.', '#', '.', '#', '#', '#', '.', '.'},
				[]rune{'.', '#', '.', '.', '#', '.', '.', '.', '.', '.'},
				[]rune{'.', '.', '#', '.', '.', '.', '.', '#', '.', '#'},
				[]rune{'#', '.', '.', '#', '.', '.', '.', '.', '#', '.'},
				[]rune{'.', '#', '#', '.', '#', '.', '.', '#', '#', '#'},
				[]rune{'#', '#', '.', '.', '.', '#', '.', '.', '#', '.'},
				[]rune{'.', '#', '.', '.', '.', '.', '#', '#', '#', '#'},
			},
			expected: Point{x: 5, y: 8},
		},
		{
			grid: [][]rune{
				[]rune{'#', '.', '#', '.', '.', '.', '#', '.', '#', '.'},
				[]rune{'.', '#', '#', '#', '.', '.', '.', '.', '#', '.'},
				[]rune{'.', '#', '.', '.', '.', '.', '#', '.', '.', '.'},
				[]rune{'#', '#', '.', '#', '.', '#', '.', '#', '.', '#'},
				[]rune{'.', '.', '.', '.', '#', '.', '#', '.', '#', '.'},
				[]rune{'.', '#', '#', '.', '.', '#', '#', '#', '.', '#'},
				[]rune{'.', '.', '#', '.', '.', '.', '#', '#', '.', '.'},
				[]rune{'.', '.', '#', '#', '.', '.', '.', '.', '#', '#'},
				[]rune{'.', '.', '.', '.', '.', '.', '#', '.', '.', '.'},
				[]rune{'.', '#', '#', '#', '#', '.', '#', '#', '#', '.'},
			},
			expected: Point{x: 1, y: 2},
		},
		{
			grid: [][]rune{
				[]rune{'.', '#', '.', '.', '#', '.', '.', '#', '#', '#'},
				[]rune{'#', '#', '#', '#', '.', '#', '#', '#', '.', '#'},
				[]rune{'.', '.', '.', '.', '#', '#', '#', '.', '#', '.'},
				[]rune{'.', '.', '#', '#', '#', '.', '#', '#', '.', '#'},
				[]rune{'#', '#', '.', '#', '#', '.', '#', '.', '#', '.'},
				[]rune{'.', '.', '.', '.', '#', '#', '#', '.', '.', '#'},
				[]rune{'.', '.', '#', '.', '#', '.', '.', '#', '.', '#'},
				[]rune{'#', '.', '.', '#', '.', '#', '.', '#', '#', '#'},
				[]rune{'.', '#', '#', '.', '.', '.', '#', '#', '.', '#'},
				[]rune{'.', '.', '.', '.', '.', '#', '.', '#', '.', '.'},
			},
			expected: Point{x: 6, y: 3},
		},
		{
			grid: [][]rune{
				[]rune{'.', '#', '.', '.', '#', '#', '.', '#', '#', '#', '.', '.', '.', '#', '#', '#', '#', '#', '#', '#'},
				[]rune{'#', '#', '.', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '.', '.', '#', '#', '.'},
				[]rune{'.', '#', '.', '#', '#', '#', '#', '#', '#', '.', '#', '#', '#', '#', '#', '#', '#', '#', '.', '#'},
				[]rune{'.', '#', '#', '#', '.', '#', '#', '#', '#', '#', '#', '#', '.', '#', '#', '#', '#', '.', '#', '.'},
				[]rune{'#', '#', '#', '#', '#', '.', '#', '#', '.', '#', '.', '#', '#', '.', '#', '#', '#', '.', '#', '#'},
				[]rune{'.', '.', '#', '#', '#', '#', '#', '.', '.', '#', '.', '#', '#', '#', '#', '#', '#', '#', '#', '#'},
				[]rune{'#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#'},
				[]rune{'#', '.', '#', '#', '#', '#', '.', '.', '.', '.', '#', '#', '#', '.', '#', '.', '#', '.', '#', '#'},
				[]rune{'#', '#', '.', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#'},
				[]rune{'#', '#', '#', '#', '#', '.', '#', '#', '.', '#', '#', '#', '.', '.', '#', '#', '#', '#', '.', '.'},
				[]rune{'.', '.', '#', '#', '#', '#', '#', '#', '.', '.', '#', '#', '.', '#', '#', '#', '#', '#', '#', '#'},
				[]rune{'#', '#', '#', '#', '.', '#', '#', '.', '#', '#', '#', '#', '.', '.', '.', '#', '#', '.', '.', '#'},
				[]rune{'.', '#', '#', '#', '#', '#', '.', '.', '#', '.', '#', '#', '#', '#', '#', '#', '.', '#', '#', '#'},
				[]rune{'#', '#', '.', '.', '.', '#', '.', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '.', '.', '.'},
				[]rune{'#', '.', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '.', '#', '#', '#', '#', '#', '#', '#'},
				[]rune{'.', '#', '#', '#', '#', '.', '#', '.', '#', '#', '#', '.', '#', '#', '#', '.', '#', '.', '#', '#'},
				[]rune{'.', '.', '.', '.', '#', '#', '.', '#', '#', '.', '#', '#', '#', '.', '.', '#', '#', '#', '#', '#'},
				[]rune{'.', '#', '.', '#', '.', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '.', '#', '#', '#'},
				[]rune{'#', '.', '#', '.', '#', '.', '#', '#', '#', '#', '#', '.', '#', '#', '#', '#', '.', '#', '#', '#'},
				[]rune{'#', '#', '#', '.', '#', '#', '.', '#', '#', '#', '#', '.', '#', '#', '.', '#', '.', '.', '#', '#'},
			},
			expected: Point{x: 11, y: 13},
		},
	}

	for i, test := range tests {
		got, _ := FindBestPosition(test.grid, true)
		if got != test.expected {
			t.Errorf("%d: Got %+v, expected %+v", i, got, test.expected)
		}
	}
}

func TestVaporize(t *testing.T) {
	tests := []struct {
		grid     [][]rune
		expected Point
	}{
		{
			grid: [][]rune{
				[]rune{'.', '#', '.', '.', '#', '#', '.', '#', '#', '#', '.', '.', '.', '#', '#', '#', '#', '#', '#', '#'},
				[]rune{'#', '#', '.', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '.', '.', '#', '#', '.'},
				[]rune{'.', '#', '.', '#', '#', '#', '#', '#', '#', '.', '#', '#', '#', '#', '#', '#', '#', '#', '.', '#'},
				[]rune{'.', '#', '#', '#', '.', '#', '#', '#', '#', '#', '#', '#', '.', '#', '#', '#', '#', '.', '#', '.'},
				[]rune{'#', '#', '#', '#', '#', '.', '#', '#', '.', '#', '.', '#', '#', '.', '#', '#', '#', '.', '#', '#'},
				[]rune{'.', '.', '#', '#', '#', '#', '#', '.', '.', '#', '.', '#', '#', '#', '#', '#', '#', '#', '#', '#'},
				[]rune{'#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#'},
				[]rune{'#', '.', '#', '#', '#', '#', '.', '.', '.', '.', '#', '#', '#', '.', '#', '.', '#', '.', '#', '#'},
				[]rune{'#', '#', '.', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#'},
				[]rune{'#', '#', '#', '#', '#', '.', '#', '#', '.', '#', '#', '#', '.', '.', '#', '#', '#', '#', '.', '.'},
				[]rune{'.', '.', '#', '#', '#', '#', '#', '#', '.', '.', '#', '#', '.', '#', '#', '#', '#', '#', '#', '#'},
				[]rune{'#', '#', '#', '#', '.', '#', '#', '.', '#', '#', '#', '#', '.', '.', '.', '#', '#', '.', '.', '#'},
				[]rune{'.', '#', '#', '#', '#', '#', '.', '.', '#', '.', '#', '#', '#', '#', '#', '#', '.', '#', '#', '#'},
				[]rune{'#', '#', '.', '.', '.', '#', '.', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '.', '.', '.'},
				[]rune{'#', '.', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '.', '#', '#', '#', '#', '#', '#', '#'},
				[]rune{'.', '#', '#', '#', '#', '.', '#', '.', '#', '#', '#', '.', '#', '#', '#', '.', '#', '.', '#', '#'},
				[]rune{'.', '.', '.', '.', '#', '#', '.', '#', '#', '.', '#', '#', '#', '.', '.', '#', '#', '#', '#', '#'},
				[]rune{'.', '#', '.', '#', '.', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '.', '#', '#', '#'},
				[]rune{'#', '.', '#', '.', '#', '.', '#', '#', '#', '#', '#', '.', '#', '#', '#', '#', '.', '#', '#', '#'},
				[]rune{'#', '#', '#', '.', '#', '#', '.', '#', '#', '#', '#', '.', '#', '#', '.', '#', '.', '.', '#', '#'},
			},
			expected: Point{x: 8, y: 2},
		},
	}

	for i, test := range tests {
		got := VaporizeAsteroids(test.grid, Point{x: 11, y: 13}, true)
		if got != test.expected {
			t.Errorf("%d: Got %+v, expected %+v", i, got, test.expected)
		}
	}
}