// Phase 4: Converter resolution.
//
// A Converter atomically turns inputs into outputs: when active it checks that
// every incoming edge can be fully satisfied; if so it consumes all incoming
// rates and produces all outgoing rates (respecting destination capacity),
// otherwise nothing happens. This models "spend N of X to get M of Y" (e.g.
// buy a building). Modifiers and activators apply to its edges as usual.

///|
/// Resolve every active converter, mutating `work` and `flows` in place.
fn process_converters(
  diagram : Diagram,
  state : SimState,
  work : Array[Int],
  flows : Array[Int],
) -> Unit {
  let edges = diagram.resources
  for ci in 0.. true
      _ => false
    }
    if !is_conv || !node_active(diagram, state, ci) {
      continue
    }
    // Collect incoming requirements.
    let in_idx : Array[Int] = []
    let in_from : Array[Int] = []
    let in_req : Array[Int] = []
    for ei in 0..
          effective_rate(diagram, state, ei, resolve_rate(e.rate, state, 0))
        _ =>
          effective_rate(
            diagram,
            state,
            ei,
            resolve_rate(e.rate, state, work[e.from]),
          )
      }
      in_idx.push(ei)
      in_from.push(e.from)
      in_req.push(req)
    }
    // Atomic: every input must be fully available.
    let mut ok = true
    for k in 0.. in_req[k]
        _ => work[in_from[k]]
      }
      if avail < in_req[k] {
        ok = false
      }
    }
    if !ok {
      continue
    }
    // Consume inputs.
    for k in 0.. ()
        _ => work[in_from[k]] = work[in_from[k]] - in_req[k]
      }
      flows[in_idx[k]] = in_req[k]
    }
    // Produce outputs (respecting capacity; drains/sources never store).
    for ei in 0.. {
          let room = cap - work[e.to]
          if amt > room {
            amt = room
          }
        }
        None => ()
      }
      if amt < 0 {
        amt = 0
      }
      match to.kind {
        Drain | Source => ()
        _ => work[e.to] = work[e.to] + amt
      }
      flows[ei] = amt
    }
  }
}