import { Material } from "./parser.ts";
import { Condition, parseInput, Workflow } from "./parser.ts";

const input = await Deno.readTextFile("input.txt");
const parsed = parseInput(input);
// await Deno.writeTextFile("input.json", 
// JSON.stringify(parsed, null, 2));

function ifCond(cond: Condition, material: Material) {
    const value = material[cond.quality];
    // console.log(value, cond.cond, cond.value);
    return cond.cond === ">" ? value > cond.value : (
        cond.cond === "<" ? value < cond.value :
            false);
}

class Executor {
    workflowTable: Map<string, Workflow>
    constructor(rules: Workflow[]) {
        this.workflowTable = new Map();
        for (const rule of rules) {
            this.workflowTable.set(rule.name, rule);
        }
    }

    execute(material: Material) {
        let gotoRules = this.workflowTable.get("in")!;
        
        for (; ;) {
            let dest = gotoRules.always;
            for (const gotoRule of gotoRules.rules) {
                if (ifCond(gotoRule.condition, material)) {
                    dest = gotoRule.dest;
                    break;
                }
            }
            if (dest === "A") return "A";
            if (dest === "R") return "R";
            gotoRules = this.workflowTable.get(dest)!;
        }
    }
}
function sumMaterials(materials: Material[]) {
    let sum = 0;
    for (const material of materials) {
        sum += material.x;
        sum += material.m;
        sum += material.a;
        sum += material.s;
    }
    return sum;
}

const executor = new Executor(parsed.rules);

let acc = [];
for (const material of parsed.materials) {
    const result = executor.execute(material);
    console.log(material ,result);
    if (result === "A") {
        acc.push(material);
    }
}
console.log(sumMaterials(acc));