package main

import (
	"AOC2021/src/helper"
	"fmt"
	"os"
)

func main() {
	args := os.Args[1:]
	input, err := helper.GetInput(args[0])
	if err != nil {
		fmt.Println(err)
	}
	field := make([][]rune, len(input))
	for i, row := range input {
		field[i] = []rune(row)
	}
	run := true
	counter := 0
	for run {
		run = !step(&field)
		counter++
	}
	fmt.Println(counter)
}

func step(field *[][]rune) (noMovesFound bool) {
	toEast := getAllToMove(field, '>')
	executeToMove(field, toEast)
	toSouth := getAllToMove(field, 'v')
	executeToMove(field, toSouth)
	noMovesFound = len(toEast) == 0 && len(toSouth) == 0
	return
}

func executeToMove(field *[][]rune, toMove [][4]int) {
	for _, move := range toMove {
		cucumberType := (*field)[move[0]][move[1]]
		(*field)[move[0]][move[1]] = '.'
		(*field)[move[2]][move[3]] = cucumberType
	}
}

func getAllToMove(field *[][]rune, cucumberType rune) [][4]int {
	toMove := [][4]int{}
	for i, row := range *field {
		for j, _ := range row {
			if (*field)[i][j] == cucumberType {
				destiny := getDestiny(field, i, j)
				if (*field)[destiny[0]][destiny[1]] == '.' {
					toMove = append(toMove, [4]int{i, j, destiny[0], destiny[1]})
				}
			}
		}
	}
	return toMove
}

func getDestiny(field *[][]rune, i int, j int) [2]int {
	switch (*field)[i][j] {
	case '>':
		j++
		if j == len((*field)[i]) {
			j = 0
		}
		break
	case 'v':
		i++
		if i == len(*field) {
			i = 0
		}
		break

	}
	return [2]int{i, j}
}

func printField(field *[][]rune) {
	for _, row := range *field {
		fmt.Println(string(row))
	}
	fmt.Println()
}
