// Example: round-trip through the in-memory `MemoryContext` server
// using `MockRuntime`. No real network or serial device required.
//
// Run with: `moon run --target native src/examples/mock_client_demo.mbt`

///|
async fn main {
  // Create an in-memory server with 16 coils and 16 registers.
  let service = @server.MemoryContext::new(16, 16)
  // Seed a known pattern in the holding registers.
  ignore(service.holding_registers.set(0, 0x1111))
  ignore(service.holding_registers.set(1, 0x2222))

  // Build a high-level client context backed by the in-memory service.
  let runtime = @client.MockRuntime::new(service)
  let ctx : @client.Context[@client.MockRuntime] = @client.Context::new(
    runtime,
    @lib.Slave::new(1),
  )

  // Read 2 holding registers.
  match @client.Reader::read_holding_registers(ctx, 0, 2) {
    Ok(Ok(words)) => {
      println("ReadHoldingRegisters => \{words.length()} words")
      for i in 0.. println("Server exception: \{e.description()}")
    Err(e) => println("Transport error: " + e.to_string())
  }

  // Write a single register.
  match @client.Writer::write_single_register(ctx, 0, 0xCAFE) {
    Ok(Ok(_)) => println("WriteSingleRegister OK")
    Ok(Err(e)) => println("Server exception: \{e.description()}")
    Err(e) => println("Transport error: " + e.to_string())
  }

  // Read it back.
  match @client.Reader::read_holding_registers(ctx, 0, 1) {
    Ok(Ok(words)) => {
      println(
        "After write: [0] = 0x\{words[0].to_int().to_string(radix=16)}",
      )
    }
    _ => ()
  }

  // Try reading an illegal address.
  match @client.Reader::read_holding_registers(ctx, 1000, 1) {
    Ok(Err(e)) =>
      println("Expected exception for OOB addr: \{e.description()}")
    _ => println("Unexpected: should have been an exception")
  }

  // Disconnect the client.
  match ctx.disconnect() {
    Ok(_) => println("Disconnected cleanly")
    Err(e) => println("Disconnect failed: " + e.to_string())
  }
}