#!/usr/bin/env ruby
# frozen_string_literal: true

require "pathname"

Aunt = Struct.new(
  :id, :children, :cats,
  :samoyeds, :pomeranians, :akitas, :vizslas,
  :goldfish, :trees, :cars, :perfumes,
  keyword_init: true
)

KNOWN = Aunt.new(
  children: 3,
  cats: 7,
  samoyeds: 2,
  pomeranians: 3,
  akitas: 0,
  vizslas: 0,
  goldfish: 5,
  trees: 3,
  cars: 2,
  perfumes: 1
).freeze

def parse_file(file)
  file.each_line.map do |line|
    line.partition(": ") => [name, _, tail]
    things = tail.split(", ").map { |x| x.split(": ") }.map { |k, v| [k.to_sym, v.to_i] }.to_h
    Aunt.new(id: name.split.last.to_i, **things)
  end
end

def find_aunt(aunts)
  aunts.select do |aunt|
    KNOWN.each_pair.all? { |prop, val| !(val && aunt[prop]) || aunt[prop] == val }
  end
end

def find_real_aunt(aunts)
  aunts.select do |aunt|
    KNOWN.each_pair.all? do |prop, val|
      next true unless val && aunt[prop]

      case prop
      when :cats, :trees then aunt[prop] > val
      when :promeranians, :goldfish then aunt[prop] < val
      else aunt[prop] == val
      end
    end
  end
end

def main(file_paths)
  file_paths.each do |file_path|
    puts "File: #{file_path}"

    aunts = parse_file(file_path)

    solution1 = find_aunt(aunts).first&.id
    puts "  solution 1: #{solution1}"

    solution2 = find_real_aunt(aunts).first&.id
    puts "  solution 2: #{solution2}"
  end
end

main(ARGV.map { |x| Pathname(x) })