#Requires -Version 7.0
<#
.SYNOPSIS
  End-to-end CLI test for the Modbus-TCP driver bridged through the OtOpcUa server.

.DESCRIPTION
  Five assertions:
    1. `otopcua-modbus-cli probe` hits the simulator
    2. Driver-loopback write + read-back via modbus-cli
    3. Forward bridge: modbus-cli writes HR[200], OPC UA client reads the bridged NodeId
    4. Reverse bridge: OPC UA client writes the NodeId, modbus-cli reads HR[200]
    5. Subscribe-sees-change: OPC UA subscription observes a modbus-cli write

  Requires a running Modbus simulator on localhost:5020 (the pymodbus fixture
  default — see tests/.../Modbus.IntegrationTests/Docker/docker-compose.yml)
  and a running OtOpcUa server whose config DB has a Modbus DriverInstance
  bound to that simulator + a Tag at HR[200] UInt16 published under the
  NodeId passed via -BridgeNodeId.

  NOTE: HR[200] (not HR[100]) — pymodbus standard.json makes HR[100] an
  auto-incrementing register that mutates every poll, so loopback writes
  can't be verified there.

.PARAMETER ModbusHost
  Host:port of the Modbus simulator. Default 127.0.0.1:5020.

.PARAMETER OpcUaUrl
  Endpoint URL of the OtOpcUa server. Default opc.tcp://localhost:4840.

.PARAMETER BridgeNodeId
  OPC UA NodeId the OtOpcUa server publishes the HR[100] tag at. Set per your
  server config — e.g. 'ns=2;s=/warsaw/modbus-sim/HR_100'. Required.

.EXAMPLE
  .\test-modbus.ps1 -BridgeNodeId "ns=2;s=/warsaw/modbus-sim/HR_100"
#>

param(
    [string]$ModbusHost = "127.0.0.1:5020",
    [string]$OpcUaUrl = "opc.tcp://localhost:4840",
    [Parameter(Mandatory)] [string]$BridgeNodeId
)

$ErrorActionPreference = "Stop"
. "$PSScriptRoot/_common.ps1"

$hostPart, $portPart = $ModbusHost.Split(":")
$port = [int]$portPart

$modbusCli = Get-CliInvocation `
    -ProjectFolder "src/Drivers/Cli/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Cli" `
    -ExeName "otopcua-modbus-cli"
$opcUaCli = Get-CliInvocation `
    -ProjectFolder "src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI" `
    -ExeName "otopcua-cli"

$commonModbus = @("-h", $hostPart, "-p", $port)
$results = @()

$results += Test-Probe `
    -Cli $modbusCli `
    -ProbeArgs (@("probe") + $commonModbus)

$writeValue = Get-Random -Minimum 1 -Maximum 9999
$results += Test-DriverLoopback `
    -Cli $modbusCli `
    -WriteArgs (@("write") + $commonModbus + @("-r", "HoldingRegisters", "-a", "200", "-t", "UInt16", "-v", $writeValue)) `
    -ReadArgs  (@("read")  + $commonModbus + @("-r", "HoldingRegisters", "-a", "200", "-t", "UInt16")) `
    -ExpectedValue "$writeValue"

$bridgeValue = Get-Random -Minimum 10000 -Maximum 19999
$results += Test-ServerBridge `
    -DriverCli $modbusCli `
    -DriverWriteArgs (@("write") + $commonModbus + @("-r", "HoldingRegisters", "-a", "200", "-t", "UInt16", "-v", $bridgeValue)) `
    -OpcUaCli $opcUaCli `
    -OpcUaUrl $OpcUaUrl `
    -OpcUaNodeId $BridgeNodeId `
    -ExpectedValue "$bridgeValue"

$reverseValue = Get-Random -Minimum 20000 -Maximum 29999
$results += Test-OpcUaWriteBridge `
    -OpcUaCli $opcUaCli `
    -OpcUaUrl $OpcUaUrl `
    -OpcUaNodeId $BridgeNodeId `
    -DriverCli $modbusCli `
    -DriverReadArgs (@("read") + $commonModbus + @("-r", "HoldingRegisters", "-a", "200", "-t", "UInt16")) `
    -ExpectedValue "$reverseValue"

$subValue = Get-Random -Minimum 30000 -Maximum 39999
$results += Test-SubscribeSeesChange `
    -OpcUaCli $opcUaCli `
    -OpcUaUrl $OpcUaUrl `
    -OpcUaNodeId $BridgeNodeId `
    -DriverCli $modbusCli `
    -DriverWriteArgs (@("write") + $commonModbus + @("-r", "HoldingRegisters", "-a", "200", "-t", "UInt16", "-v", $subValue)) `
    -ExpectedValue "$subValue"

Write-Summary -Title "Modbus e2e" -Results $results
if ($results | Where-Object { -not $_.Passed }) { exit 1 }
