/**
 * component-loader：`code` 零件解析測試（#29 發現的白名單缺口）。
 *
 * 背景：workflow 寫 `component: code` 時，component-loader 解析鏈 step 1-6 都不命中
 * （非 builtin / 非 URL / 非 hash / 非邏輯零件 binding / 非 recipe），必須靠 step 7 的
 * WASM_HTTP_RUNNER_IDS 白名單 → wasmWorkerUrl 通用推導。白名單漏 `code` 就會落到
 * step 8 直接丟「找不到零件」——graph_neighbors 等用 code 節點的 workflow 全滅。
 *
 * 驗證：
 *   1. `code` 能被解析成 runner（不 throw）。
 *   2. runner 打的 URL = arcrun-code.{WORKER_SUBDOMAIN}.workers.dev（通用推導、無寫死
 *      官方 code.arcrun.dev → self-hosted 換 WORKER_SUBDOMAIN 即落地）。
 */
import { describe, it, expect, vi, afterEach } from 'vitest';
import { env } from 'cloudflare:test';
import { createComponentLoader, wasmWorkerUrl } from '../src/lib/component-loader';
import type { Bindings } from '../src/types';

afterEach(() => {
  vi.unstubAllGlobals();
});

describe('component-loader：code 零件解析（WASM HTTP runner 白名單）', () => {
  it('wasmWorkerUrl 通用推導：code → arcrun-code.{subdomain}.workers.dev（self-hosted 換 subdomain 即成立）', () => {
    expect(wasmWorkerUrl('code', 'uncle6-me')).toBe('https://arcrun-code.uncle6-me.workers.dev');
    expect(wasmWorkerUrl('code', 'my-selfhosted-sub')).toBe('https://arcrun-code.my-selfhosted-sub.workers.dev');
  });

  it('component: code 能被解析成 runner，且 fetch 打 subdomain 推導的 URL', async () => {
    const fakeEnv = {
      ...env,
      WORKER_SUBDOMAIN: 'test-sub',
    } as unknown as Bindings;

    const loader = createComponentLoader(fakeEnv);
    // 白名單漏 `code` 時這裡就 throw「找不到零件 "code"」（#29 的故障型態）
    const runner = await loader('code');
    expect(typeof runner).toBe('function');

    // stub fetch 捕 URL：證明 runner 打的是通用推導 URL，非寫死官方域名
    const calledUrls: string[] = [];
    const fetchSpy = vi.fn(async (url: unknown) => {
      calledUrls.push(String(url));
      return new Response(JSON.stringify({ success: true, data: { ok: true } }), {
        status: 200,
        headers: { 'Content-Type': 'application/json' },
      });
    });
    vi.stubGlobal('fetch', fetchSpy);

    const result = await runner({ code: 'return {ok:true}', input: {} }) as Record<string, unknown>;
    expect(fetchSpy).toHaveBeenCalledTimes(1);
    expect(calledUrls[0]).toBe('https://arcrun-code.test-sub.workers.dev');
    expect(result.success).toBe(true);
  });
});
