package main

import (
	"bufio"
	"fmt"
	"os"
	"regexp"
	"strconv"
)

func calcScore(s [][]string) int {
  result := 0
  for i := range s {
    if len(s[i]) % 2 == 0 {
      fmt.Println("The following valid update has an even length, so cannot calculate the middle page: ", s[i])
    } else {
      middle := (len(s[i]) + 1) / 2
      middlePage, _ := strconv.Atoi(s[i][middle - 1])
      result = result + middlePage
    }
  }
  return result
}

func main() {
  file, _ := os.Open("test")
  defer file.Close()
  scanner := bufio.NewScanner(file)
  rule := regexp.MustCompile(`[0-9]+\|[0-9]+`)
  update := regexp.MustCompile(`^(\d+(,\d+)*)$`)
  rules := []string{}
  updates := []string{}
  for scanner.Scan() {
    line := scanner.Text()
    ruleMatches := rule.FindAllString(line, -1)
    updateMatches := update.FindAllString(line, -1)
    rules = append(rules, ruleMatches...)
    updates = append(updates, updateMatches...)
  }
//  fmt.Println("Rules:   ", rules[0])
//  fmt.Println("Updates: ", updates[0])
  number := regexp.MustCompile(`[0-9]+`)
  validUpdates := [][]string{}
  invalidUpdates := [][]string{}
  for i := range updates { //FOR EACH UPDATE
    validUpdate := true
    updateNumbers := number.FindAllString(updates[i], -1) 
    for j:=1; j<len(updateNumbers); j++ { //FOR EACH NUMBER OF THE UPDATE
      for k := range rules { //FOR EACH RULE
        ruleNumbers := number.FindAllString(rules[k], -1)
        if updateNumbers[j] != ruleNumbers[0] {
          continue
        } else {
          for l:=0; l<j; l++ { //FOR EACH NUMBER UNTIL THIS ONE IN THE REPORT
            if updateNumbers[l] == ruleNumbers[1] {
              validUpdate = false
              break
            }
          }
        }
      }
      if validUpdate == false {
        break
      }
    }
    if validUpdate {
      validUpdates = append(validUpdates, updateNumbers)
    } else {
      invalidUpdates = append(invalidUpdates, updateNumbers)
    }
//    fmt.Println("Update numbers:      ", updateNumbers)
//    fmt.Println("updateNumbers length:", len(updateNumbers))
  }
//  fmt.Println("Valid Updates: ", validUpdates)
//  fmt.Println("Valid updates number: ", len(validUpdates))
  result := calcScore(validUpdates)
  fmt.Println("Valid updates: ", validUpdates)
  fmt.Println("Invalid updates: ", invalidUpdates)
  fmt.Println("Result: ", result)
}
