package main

import (
	"bufio"
	"bytes"
	"fmt"
	"math"
	"os"
	"strconv"
)

func main() {
	numbers, err := readInput("input")
	if err != nil {
		fmt.Printf("Error encountered: %s", err)
		return
	}

	// Alright, I am going for the simplest and most (reasonably) computationally expensive solution
	// So like... Don't hate on me for this XD
	findMinMax := func(slice []int) (min int, max int) {
		min = slice[0]
		max = slice[0]
		for _, value := range slice {
			if value < min {
				min = value
			}
			if value > max {
				max = value
			}
		}
		return
	}

	min, max := findMinMax(numbers)
	leastFuel := math.MaxInt
	position := min
	for i := min; i < max; i++ {
		fuel, _ := calculateFuel(numbers, i)
		//fmt.Printf("For position %d fuel costs %d\n", i, fuel)
		if fuel < leastFuel {
			leastFuel = fuel
			position = i
		}
	}

	fmt.Printf("The least amount of fuel is: %d at position %d\n", leastFuel, position)
}

func calculateFuel(numbers []int, target int) (int, error) {
	totalFuel := 0
	// For position target, calculate fuel costs
	for i := 0; i < len(numbers); i++ {
		fuelCosts := 1
		for j := 0; j < int(math.Abs(float64(numbers[i]-target))); j++ {
			totalFuel += fuelCosts
			fuelCosts++
		}
	}
	return totalFuel, nil
}

func readInput(inputfile string) ([]int, error) {
	file, err := os.OpenFile(inputfile, 0, 0)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	splitfunc := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
		nextIndex := bytes.IndexByte(data, ',')
		if nextIndex > 0 {
			// Returning the next position aka taking only the stuff up to nextIndex and slicing off everything else
			buffer := data[:nextIndex]
			// nextIndex plus 1 because index is at the comma, we want the next number
			return nextIndex + 1, bytes.TrimSpace(buffer), nil
		}

		// If we are at the end of the buffer, then return the entire buffer, but only if there is data
		if atEOF {
			if len(data) > 0 {
				return len(data), bytes.TrimSpace(data), nil
			}
		}

		// https://github.com/kgrz/reading-files-in-go/blob/master/comma-separated-string.go
		// For more info
		return 0, nil, nil
	}

	scanner := bufio.NewScanner(file)
	scanner.Split(splitfunc)

	numbers := make([]int, 0)
	for scanner.Scan() {
		number, err := strconv.Atoi(scanner.Text())
		if err != nil {
			fmt.Printf("Error converting string to integer\n")
			return nil, err
		}
		numbers = append(numbers, number)
	}
	return numbers, nil
}