-- Integration-test driver: exercises the REAL trapos-cloud client (libcloud)
-- against a real gateway. Reuses startSession/request/onMessage so the test covers
-- production client code + CraftOS JSON serialization quirks.
--
-- Args (via shell.run): url, secret, scenario, reconnectDelay.
--   url      gateway origin, e.g. ws://127.0.0.1:PORT (daemon appends /gateway)
--   secret   shared secret ('' => none)
--   scenario health | auth | idle  (default: health)
--
-- Each scenario prints a single sentinel line the TS test asserts on.
-- NOTE: shell.run re-tokenizes its arguments, so empty-string args are dropped and
-- positions shift. The harness passes '-' as the "no secret" sentinel instead of ''.
local args = { ... };
local url = args[1];
local secret = args[2];
if secret == '' or secret == '-' then secret = nil; end
local scenario = args[3] or 'health';
local reconnectDelay = tonumber(args[4] or '');

local createCloud = require('/apis/libcloud');
local createEventLoop = require('/apis/eventloop');

_G.bootEventLoop = createEventLoop();
local cloud = createCloud();
local sessionOpts = {
  eventloop = _G.bootEventLoop,
  url = url,
  secret = secret,
  os = os,
};
if reconnectDelay then
  sessionOpts.reconnectDelay = reconnectDelay;
end
local session = cloud.startSession(sessionOpts);

-- Connect, probe the gateway, report opencodeOk.
local function runHealth()
  os.pullEvent('trapos_cloud_connected');
  local ok, payload = cloud.request('probe_server');
  if ok then
    print('__CLOUD_HEALTH__ serverOk=' .. tostring(payload.serverOk)
      .. ' opencodeOk=' .. tostring(payload.opencodeOk));
  else
    print('__CLOUD_HEALTH__ error=' .. tostring(type(payload) == 'table' and payload.code));
  end
end

-- Poll the hello outcome: ready => ok:true, terminal lastError => ok:false code.
local function runAuth()
  local deadline = os.epoch('utc') + 8000;
  while os.epoch('utc') < deadline do
    if session.isReady() then
      print('__CLOUD_HELLO__ ok=true');
      return;
    end
    local err = session.lastError();
    if err then
      print('__CLOUD_HELLO__ ok=false code=' .. tostring(err));
      return;
    end
    os.sleep(0.1);
  end
  print('__CLOUD_HELLO__ ok=false code=timeout');
end

-- Connect and stay registered so the TS side can drive the gateway->computer
-- direction (reverse ping) or assert registry state (duplicate newest-wins).
local function runIdle()
  os.pullEvent('trapos_cloud_connected');
  print('__CLOUD_READY__ ' .. cloud.traposId(os));
  os.sleep(10);
end

local scenarios = { health = runHealth, auth = runAuth, idle = runIdle };
local run = scenarios[scenario] or runHealth;

parallel.waitForAny(
  function() _G.bootEventLoop.runLoop(true); end,
  run
);

os.shutdown();
