package main

import (
	"fmt"
	"log"
	"os"
	"regexp"
	"strconv"
	"strings"

	"git.annabunch.es/annabunches/adventofcode/2020/lib/util"
)

func countValidPassports(input []string, step string) int {
	total := 0
	for _, line := range input {
		if strings.Contains(line, "byr:") &&
			strings.Contains(line, "iyr:") &&
			strings.Contains(line, "eyr:") &&
			strings.Contains(line, "hgt:") &&
			strings.Contains(line, "hcl:") &&
			strings.Contains(line, "ecl:") &&
			strings.Contains(line, "pid:") {
			if step == "1" {
				total += 1
				continue
			}

			i := validatePassport(line)
			if i == 0 {
				log.Printf("Failed: %s", line)
			} else {
				log.Printf("Passed: %s", line)
			}

			total += i
		}
	}

	return total
}

func validatePassport(input string) int {
	fields := strings.Split(input, " ")
	for _, field := range fields {
		if field == "" {
			continue
		}

		subFields := strings.Split(field, ":")
		if len(subFields) != 2 {
			log.Panicf("Failed to split subfields on '%s'", field)
		}
		name := subFields[0]
		value := subFields[1]

		switch name {
		case "byr":
			ivalue := makeInt(value)
			if ivalue < 1920 || ivalue > 2002 {
				return 0
			}
		case "iyr":
			ivalue := makeInt(value)
			if ivalue < 2010 || ivalue > 2020 {
				return 0
			}
		case "eyr":
			ivalue := makeInt(value)
			if ivalue < 2020 || ivalue > 2030 {
				return 0
			}
		case "hgt":
			if strings.HasSuffix(value, "cm") {
				ivalue := makeInt(strings.TrimSuffix(value, "cm"))
				if ivalue < 150 || ivalue > 193 {
					return 0
				}
			} else if strings.HasSuffix(value, "in") {
				ivalue := makeInt(strings.TrimSuffix(value, "in"))
				if ivalue < 59 || ivalue > 76 {
					return 0
				}
			} else {
				return 0
			}
		case "hcl":
			match, err := regexp.MatchString("^#[0-9a-f]{6}$", value)
			if err != nil {
				log.Panicf(err.Error())
			}
			if !match {
				return 0
			}
		case "ecl":
			if value != "amb" &&
				value != "blu" &&
				value != "brn" &&
				value != "gry" &&
				value != "grn" &&
				value != "hzl" &&
				value != "oth" {
				return 0
			}
		case "pid":
			match, err := regexp.MatchString("^[0-9]{9}$", value)
			if err != nil {
				log.Panicf(err.Error())
			}
			if !match {
				return 0
			}
		case "cid":
		default:
			log.Panicf("Got bad field data: ")
		}
	}

	return 1
}

func makeInt(input string) int {
	i, err := strconv.Atoi(input)
	if err != nil {
		log.Panicf(err.Error())
	}
	return i
}

func main() {
	step := os.Args[1]
	values := util.InputParserStrings(os.Args[2])
	values = util.SplitOnBlankLine(values)

	fmt.Println("Valid Passports:", countValidPassports(values, step))
}