///|
/// MoonPLC 命令行交互与工业场景仿真器
fn main {
  println("================================================================")
  println("       __  ___                     ____  __    ______           ")
  println("      /  |/  /___  ____  ____     / __ \\/ /   / ____/           ")
  println("     / /|_/ / __ \\/ __ \\/ __ \\   / /_/ / /   / /                ")
  println("    / /  / / /_/ / /_/ / / / /  / ____/ /___/ /___              ")
  println("   /_/  /_/\\____/\\____/_/ /_/  /_/   /_____/\\____/              ")
  println("================================================================")
  println("   IEC 61131-3 Soft PLC Runtime & Structured Text Simulator     ")
  println("   Pure MoonBit Implementation | WebAssembly & Edge Ready       ")
  println("================================================================\n")

  // -------------------------------------------------------------
  // 场景 1:梯形图编译 - 电机启保停自锁控制
  // -------------------------------------------------------------
  println("[SCENARIO 1] Ladder Diagram: Motor Start-Stop Self-Hold Circuit")
  println("----------------------------------------------------------------")
  println("  Logic: Motor_Run := (Start_Btn OR Motor_Run) AND NOT Stop_Btn;")

  let plc1 = @lib.MoonPlc::new("Motor_Controller")

  let b1 = @lib.LadderNode::Leaf(@lib.Contact::NormallyOpen("Start_Btn"))
  let b2 = @lib.LadderNode::Leaf(@lib.Contact::NormallyOpen("Motor_Run"))
  let parallel_start = @lib.LadderNode::Parallel([b1, b2])
  let stop_contact = @lib.LadderNode::Leaf(
    @lib.Contact::NormallyClosed("Stop_Btn"),
  )
  let full_cond = @lib.LadderNode::Series([parallel_start, stop_contact])

  let rung = @lib.Rung::new(1, "Motor Start-Stop Circuit", full_cond, [
    @lib.Coil::Normal("Motor_Run"),
  ])
  let ld = @lib.LadderDiagram::new("Motor_Ladder")
  ld.add_rung(rung)
  plc1.load_ladder(ld)

  println("\n>> Step 1: Initial state (Buttons idle)")
  plc1.set_var("Start_Btn", @lib.PlcValue::Bool(false))
  plc1.set_var("Stop_Btn", @lib.PlcValue::Bool(false))
  plc1.cycle(10L)
  println(
    "   Cycle: " +
    plc1.cycle_count().to_string() +
    " | Motor_Run = " +
    plc1.get_var("Motor_Run").to_string_repr(),
  )

  println("\n>> Step 2: Press [START] Button (Start_Btn = TRUE)")
  plc1.set_var("Start_Btn", @lib.PlcValue::Bool(true))
  plc1.cycle(10L)
  println(
    "   Cycle: " +
    plc1.cycle_count().to_string() +
    " | Motor_Run = " +
    plc1.get_var("Motor_Run").to_string_repr() +
    " [MOTOR STARTED]",
  )

  println("\n>> Step 3: Release [START] Button (Self-holding active)")
  plc1.set_var("Start_Btn", @lib.PlcValue::Bool(false))
  plc1.cycle(10L)
  println(
    "   Cycle: " +
    plc1.cycle_count().to_string() +
    " | Motor_Run = " +
    plc1.get_var("Motor_Run").to_string_repr() +
    " [SELF-LATCH MAINTAINED]",
  )

  println("\n>> Step 4: Press [STOP] Button (Stop_Btn = TRUE)")
  plc1.set_var("Stop_Btn", @lib.PlcValue::Bool(true))
  plc1.cycle(10L)
  println(
    "   Cycle: " +
    plc1.cycle_count().to_string() +
    " | Motor_Run = " +
    plc1.get_var("Motor_Run").to_string_repr() +
    " [MOTOR STOPPED]",
  )

  // -------------------------------------------------------------
  // 场景 2:ST 语言 - 十字路口交通灯与定时器控制
  // -------------------------------------------------------------
  println("\n================================================================")
  println("[SCENARIO 2] Structured Text: Traffic Light Timing Control")
  println("----------------------------------------------------------------")

  let traffic_st =
    #|PROGRAM TrafficLight
    #|VAR
    #|  Sensor_Car  AT %IX0.0 : BOOL := FALSE;
    #|  Light_Red   AT %QX0.0 : BOOL := TRUE;
    #|  Light_Green AT %QX0.1 : BOOL := FALSE;
    #|  Light_Amber AT %QX0.2 : BOOL := FALSE;
    #|  Timer_Pass  : TON;
    #|END_VAR
    #|
    #|IF Sensor_Car THEN
    #|  Light_Green := TRUE;
    #|  Light_Red   := FALSE;
    #|  Timer_Pass(IN := TRUE, PT := T#100ms);
    #|  IF Timer_Pass.Q THEN
    #|    Light_Green := FALSE;
    #|    Light_Amber := TRUE;
    #|  END_IF;
    #|ELSE
    #|  Light_Red   := TRUE;
    #|  Light_Green := FALSE;
    #|  Light_Amber := FALSE;
    #|END_IF;
    #|END_PROGRAM

  let plc2 = @lib.MoonPlc::new("Traffic_Controller")
  plc2.load_st(traffic_st)

  println(">> Initial: No cars detected")
  plc2.cycle(20L)
  println("   %QX0.0 (RED):   " + plc2.get_output_bool("%QX0.0").to_string())
  println("   %QX0.1 (GREEN): " + plc2.get_output_bool("%QX0.1").to_string())
  println("   %QX0.2 (AMBER): " + plc2.get_output_bool("%QX0.2").to_string())

  println("\n>> Car Arrives! Triggering %IX0.0 = TRUE")
  plc2.set_input_bool("%IX0.0", true)
  plc2.cycle(50L)
  println(
    "   [At 50ms]  RED = " +
    plc2.get_output_bool("%QX0.0").to_string() +
    " | GREEN = " +
    plc2.get_output_bool("%QX0.1").to_string() +
    " | AMBER = " +
    plc2.get_output_bool("%QX0.2").to_string(),
  )

  plc2.cycle(60L)
  println(
    "   [At 110ms] RED = " +
    plc2.get_output_bool("%QX0.0").to_string() +
    " | GREEN = " +
    plc2.get_output_bool("%QX0.1").to_string() +
    " | AMBER = " +
    plc2.get_output_bool("%QX0.2").to_string(),
  )

  // -------------------------------------------------------------
  // 场景 3:工业闭环控制 - 恒温水箱 PID 调节仿真
  // -------------------------------------------------------------
  println("\n================================================================")
  println(
    "[SCENARIO 3] Process Automation: Closed-Loop PID Temperature Control",
  )
  println("----------------------------------------------------------------")
  let pid = @lib.PidController::new(2.5, 800.0, 50.0)
  pid.set_limits(0.0, 100.0)
  let target_sp = 65.0
  let mut current_pv = 25.0

  println(">> Target Setpoint: 65.0°C | Initial Tank Temperature: 25.0°C")
  let mut step = 1
  while step <= 5 {
    let power = pid.compute(target_sp, current_pv, 100.0)
    current_pv = current_pv + power * 0.08 - (current_pv - 25.0) * 0.02
    println(
      "   Step " +
      step.to_string() +
      " | Heater Output = " +
      power.to_int().to_string() +
      "% | Tank Temp = " +
      current_pv.to_int().to_string() +
      "°C",
    )
    step = step + 1
  }

  // -------------------------------------------------------------
  // 场景 4:工业现场总线 - Modbus 协议通信仿真
  // -------------------------------------------------------------
  println("\n================================================================")
  println("[SCENARIO 4] Fieldbus: Modbus TCP/RTU Protocol Telemetry")
  println("----------------------------------------------------------------")
  let mem = @lib.PlcMemory::new()
  let modbus = @lib.PlcModbusServer::new(mem, 1)

  println(">> SCADA Host writes Coil 0 (%QX0.0) via Modbus FC 0x05")
  let req_coil = @lib.ModbusRequest::new(
    1,
    @lib.ModbusFunction::WriteSingleCoil,
    0,
    1,
  )
  let resp_coil = modbus.handle_request(req_coil)
  println(
    "   Response Error: " +
    resp_coil.is_error.to_string() +
    " | %QX0.0 Status = " +
    mem.get_output_bool("%QX0.0").to_string(),
  )

  println(
    ">> SCADA Host writes Holding Register 40001 (%MW0) = 8848 via Modbus FC 0x06",
  )
  let req_reg = @lib.ModbusRequest::new(
    1,
    @lib.ModbusFunction::WriteSingleRegister,
    0,
    8848,
  )
  let resp_reg = modbus.handle_request(req_reg)
  println(
    "   Response Error: " +
    resp_reg.is_error.to_string() +
    " | Written Value = " +
    resp_reg.data[1].to_string(),
  )

  println("\n================================================================")
  println("MoonPLC execution simulation completed successfully!")
  println("Ready for WebAssembly browser deployment and edge compilation.")
  println("================================================================")
}