import assert from 'node:assert/strict';
import { readFile } from 'node:fs/promises';
import { join } from 'node:path';
import test from 'node:test';
import { overlayShouldRender } from '../src/overlay.js';
import type { ContinuityWorkerView } from '../src/ui-model.js';

const extensionRoot = join(import.meta.dirname, '..');

async function staticFile(name: string): Promise<string> {
  return readFile(join(extensionRoot, 'static', name), 'utf8');
}

const worker: ContinuityWorkerView = {
  workerId: 'wrk_00000000-0000-0000-0000-000000000001', label: 'UI lane', hierarchicalName: '/root/ui', assignmentTitle: 'UI lane', runId: null, runTitle: null,
  conversationState: 'idle', conversationUrl: 'https://chatgpt.com/c/one', statusLabel: 'Idle', tabId: 7, currentTab: false, policyMode: 'auto', policySource: null,
  attemptNumber: 1, autoResumeCount: 0, lastProgressAt: null, blockReason: null, pauseReason: null, noProgressAttempts: null, stallWarningAt: null, stallPausedAt: null,
  stallState: 'unavailable', recentEvents: null, needsUser: false, controlAvailable: true,
};

test('C9 popup is the primary browser-action runtime surface with required summary, current worker and navigation', async () => {
  const html = await staticFile('popup.html');
  for (const required of ['Execution Continuity', 'auto-resume-state', 'active-count', 'working-count', 'resuming-count', 'needs-you-count', 'Managed workers', 'Current conversation', 'current-actions', 'Open dashboard', 'Settings / Advanced']) {
    assert.match(html, new RegExp(required.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')));
  }
});

test('C10 overlay gate renders only for a managed worker when the global preference is enabled', () => {
  assert.equal(overlayShouldRender(null, true), false);
  assert.equal(overlayShouldRender(worker, false), false);
  assert.equal(overlayShouldRender(worker, true), true);
});

test('C11 dashboard and Advanced settings are separate surfaces with explicit run/stall capability UX', async () => {
  const dashboard = await staticFile('dashboard.html');
  const options = await staticFile('options.html');
  for (const required of ['Runtime summary', 'Run controls', 'Managed runtime', 'Stall protection', 'run-controls', 'stall-cards']) {
    assert.match(dashboard, new RegExp(required.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')));
  }
  for (const required of ['Settings / Advanced', 'Executor endpoint', 'Executor token', 'Concurrent launches', 'Managed conversations', 'overlay-visible', 'Executor ID']) {
    assert.match(options, new RegExp(required.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')));
  }
  assert.doesNotMatch(options, /Pause all after current turns|Stop run|stall-cards|worker-actions/);
});

test('dashboard source does not fake run-level control by broadcasting worker actions', async () => {
  const source = await readFile(join(extensionRoot, 'src', 'dashboard.ts'), 'utf8');
  assert.match(source, /current executor UI contract has worker-level controls only/);
  assert.match(source, /will not simulate run authority/);
  assert.doesNotMatch(source, /Promise\.all\([^\n]*performAction/);
});
