package day_03

import "core:log"
import "core:os"
import "core:strings"

Input :: struct {
	bank_len: int,
	banks:    [][]int,
}

Result1 :: int
Result2 :: int

// --- Input --- //
print_input :: proc(input: Input) {
	log.infof("%v", input)
}

parse_input_file :: proc(filepath: string) -> Input {
	input: Input

	raw_data, ok := os.read_entire_file_from_filename(filepath)
	if !ok {
		panic("oh no, could not read file")
	}
	defer delete(raw_data)

	lines, err := strings.split_lines(strings.trim_right_space(string(raw_data)))
	if err != .None {
		panic("oh no, failed splitting into lines")
	}
	defer delete(lines)

	input.banks = make([][]int, len(lines))
	for line, i in lines {
		if input.bank_len == 0 {
			input.bank_len = len(line)
		}
		bank := make([]int, input.bank_len)
		for c, j in line {
			bank[j] = int(c - '0')
		}
		input.banks[i] = bank
	}

	return input
}

free_input :: proc(input: ^Input) {
	for bank in input.banks {
		delete(bank)
	}
	delete(input.banks)
}
// --- Input --- //


// --- Helpers --- //
// --- Helpers --- //


// --- Task 1 --- //
run_task1 :: proc(input: Input) -> Result1 {
	result: Result1

	for bank in input.banks {
		a, b: int
		ai: int
		for level, i in bank[:len(bank) - 1] {
			if level > a {
				a = level
				ai = i
			}
		}
		for level in bank[ai + 1:] {
			if level > b {
				b = level
			}
		}
		result += (a * 10) + b
	}

	return result
}

print_result1 :: proc(result: Result1) {
	log.infof("Task 1: %d", result)
}
// --- Task 1 --- //


// --- Task 2 --- //
run_task2 :: proc(input: Input) -> Result2 {
	result: Result2

	for bank in input.banks {
		to_remove := input.bank_len - 12
		stack := make([]int, input.bank_len)
		defer delete(stack)
		stack_i: int
		for level in bank {
			for stack_i > 0 && to_remove > 0 && stack[stack_i - 1] < level {
				stack_i -= 1
				stack[stack_i] = 0
				to_remove -= 1
			}
			stack[stack_i] = level
			stack_i += 1
		}
		log.debugf("%v", stack)
		if to_remove > 0 {
			log.debugf("has leftovers")
		}
		smashed_stack: int
		for i in stack[:12] {
			smashed_stack = (smashed_stack * 10) + i
		}
		result += smashed_stack
	}

	return result
}

print_result2 :: proc(result: Result2) {
	log.infof("Task 2: %d", result)
}
// --- Task 2 --- //

run :: proc() {
	input := parse_input_file("input/day_03.txt")
	defer free_input(&input)

	result1 := run_task1(input)
	print_result1(result1)

	result2 := run_task2(input)
	print_result2(result2)
}