package main

import (
	"bufio"
	"log"
	"os"
	"regexp"
	"strings"
)

type passData map[string]string

var re = regexp.MustCompile(`(.*?):(.*?) `)

var fields = []struct {
	name      string
	validator func(string) bool
}{
	{"byr", byrValid},
	{"iyr", iyrValid},
	{"eyr", eyrValid},
	{"hgt", hgtValid},
	{"hcl", hclValid},
	{"ecl", eclValid},
	{"pid", pidValid},
}

func main() {
	if err := realMain(); err != nil {
		log.Println(err)
	}
}

func realMain() error {
	data, err := readInput()
	if err != nil {
		return err
	}

	var valid int
	for _, d := range data {
		var notvalid bool
		for _, f := range fields {
			value, ok := d[f.name]
			if !ok {
				notvalid = true
				break
			}
			if !f.validator(value) {
				notvalid = true
				break
			}
		}
		if !notvalid {
			valid++
		}
	}
	log.Println(valid)

	return nil
}

func readInput() ([]passData, error) {
	fd, err := os.Open("input.txt")
	if err != nil {
		return nil, err
	}
	defer fd.Close()

	var ret []passData

	buf := bufio.NewScanner(fd)
	item := strings.Builder{}
	for buf.Scan() {
		if buf.Text() != "" {
			item.WriteString(buf.Text())
			item.WriteByte(' ')
		} else {
			ret = append(ret, parseData(item.String()))
			item.Reset()
		}
	}
	ret = append(ret, parseData(item.String()))

	return ret, nil
}

func parseData(in string) passData {
	ret := passData{}

	res := re.FindAllString(in, -1)

	for _, pair := range res {
		pair = strings.TrimSpace(pair)
		p := strings.SplitAfter(pair, ":")
		ret[strings.TrimRight(p[0], ":")] = p[1]
	}

	return ret
}