///|
/// Live-scan entry point for provider CLI coverage.
///
/// These two commands construct a native transport kind (`@native.NpcapKind` /
/// `@native.RawSocketKind`) and run a no-live / live provider scan. They live in
/// the isoproject top-level orchestration layer rather than
/// `fieldbus_core/cmd/main` because linking `driver/native` (required for the
/// extenum kind variants and their handler registrations to be live) is a
/// runtime concern that must not bleed into the fieldbus_core protocol layer —
/// the fieldbus-protocol boundary forbids fieldbus_core packages from importing
/// the lockwire native runtime. On wasm-gc the open raises before any I/O, so
/// the report records the no-live failure without touching a NIC.
fn main {
  let args = @env.args()
  if args.length() >= 2 && args[1] == "workbench-server-plan" {
    let host = parse_text_option(args, "--host", default="127.0.0.1")
    let port = parse_int_option(args, "--port", 8765)
    let adapter = parse_text_option(args, "--adapter", default="windows-npcap")
    let iface = parse_text_option(
      args,
      "--iface",
      default=parse_text_option(args, "--interface", default=""),
    )
    let confirm = parse_text_option(
      args,
      "--confirm-interface",
      default=parse_text_option(args, "--confirm", default=""),
    )
    let artifact_dir = parse_text_option(
      args,
      "--artifact-dir",
      default="_build/isoproject-workbench",
    )
    let plan = @workbench.workbench_server_plan(
      config=@workbench.workbench_server_config(
        host~,
        port~,
        adapter~,
        interface_name=iface,
        confirm_interface_name=confirm,
        allow_live=has_flag(args, "--allow-live"),
        artifact_dir~,
      ),
    )
    for line in @workbench.workbench_server_plan_lines(plan) {
      println(line)
    }
    return
  }
  if args.length() >= 2 && args[1] == "profinet-live-scan" {
    let iface = parse_text_option(args, "--iface", default="")
    let backend_label = parse_text_option(args, "--backend", default="npcap")
    let allow_live = has_flag(args, "--allow-live")
    let timeout = parse_int_option(args, "--timeout-ms", 3000)
    let xid = parse_int_option(args, "--xid", 16909060)
    let kind = if backend_label == "raw-socket" {
      @native.RawSocketKind
    } else {
      @native.NpcapKind
    }
    let report = @live.live_scan_dcp_report(
      kind,
      iface,
      allow_live,
      timeout_ms=timeout,
      xid~,
    )
    for line in @live.profinet_live_scan_report_lines(report) {
      println(line)
    }
    return
  }
  if args.length() >= 2 && args[1] == "moonecat-live-scan" {
    let iface = parse_text_option(args, "--iface", default="")
    let backend_label = parse_text_option(args, "--backend", default="npcap")
    let allow_live = has_flag(args, "--allow-live")
    let timeout_ms = parse_int_option(args, "--timeout-ms", 1000)
    let kind = if backend_label == "raw-socket" {
      @native.RawSocketKind
    } else {
      @native.NpcapKind
    }
    let report = @mcat.moonecat_live_scan_report(
      kind,
      iface,
      allow_live,
      timeout_ns=timeout_ms.to_int64() * 1_000_000L,
    )
    for line in @mcat.moonecat_live_scan_report_lines(report) {
      println(line)
    }
    return
  }
  print_help()
}

///|
fn print_help() -> Unit {
  println("mokomoking2501/isoproject provider live-scan entry")
  println("commands:")
  println(
    "  - workbench-server-plan [--host 127.0.0.1] [--port 8765] [--adapter windows-npcap] [--iface NAME] [--confirm-interface NAME] [--artifact-dir DIR] [--allow-live]",
  )
  println(
    "  - profinet-live-scan --iface  [--backend npcap|raw-socket] [--timeout-ms ] [--xid ] [--allow-live]",
  )
  println(
    "  - moonecat-live-scan --iface  [--backend npcap|raw-socket] [--timeout-ms ] [--allow-live]",
  )
  println(
    "default: no-live reports only; does not open NIC unless a route is later invoked with explicit live permission",
  )
}

///|
fn parse_int_option(args : Array[String], name : String, default : Int) -> Int {
  for i in 0.. Int {
  if text == "" {
    return 0
  }
  let bytes = @utf8.encode(text)
  let mut value = 0
  for ch in bytes {
    if ch < b'0' || ch > b'9' {
      return 0
    }
    value = value * 10 + ch.to_int() - b'0'.to_int()
  }
  value
}

///|
fn parse_text_option(
  args : Array[String],
  name : String,
  default~ : String,
) -> String {
  for i in 0.. Bool {
  args.any(fn(arg) { arg == name })
}