import { describe, it, expect, vi } from 'vitest';
import { mkdtempSync, readFileSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import {
  CLAUDEX_PROXY_HOST,
  CLAUDEX_PROXY_PORT,
  CLAUDEX_PROXY_URL,
  CLAUDEX_PROXY_BINARY,
  CLAUDEX_HEALTH_PATH,
  CLAUDEX_HEALTH_URL,
  buildAuthStatusArgs,
  buildDeviceAuthArgs,
  buildServeArgs,
  parseAuthStatus,
  checkProxyBinary,
  checkAuthStatus,
  runDeviceReauth,
  probeLiveness,
  buildSystemdUnitContent,
  systemdUnitPath,
  installSystemdUnit,
  startNohupProxy,
  verifyListenerIdentity,
  runProxyPreflight,
  ensureProxyRunning,
  type AuthStatus,
  type ProxyRunResult,
  type SpawnedChild,
  type ListenerIdentity,
} from './claudex-proxy.js';

/**
 * P1 — Proxy preflight + lifecycle helpers for `mosaic yolo claudex`.
 *
 * Security-relevant invariants exercised here:
 *  - Liveness probe hits the proxy's dedicated `GET /healthz` and treats only a
 *    2xx as "alive" — a *proxy-specific* health contract, not arbitrary HTTP on
 *    the port (CWE-345: a local port-squatter must not be trusted as the proxy).
 *    This also honors spec gotcha #1 (never `curl -f` the root, which returns
 *    non-2xx): `/healthz` returns 2xx when the proxy is up, so a healthy proxy is
 *    never mistaken for dead and no duplicate proxy is spawned.
 *  - Auth-status parsing NEVER surfaces OAuth token material — only a coarse
 *    state + optional expiry — even if a token-shaped string appears in output.
 *  - The systemd unit's ExecStart never interpolates an unvalidated path
 *    (CWE-74: a CR/LF in the path could inject arbitrary systemd directives).
 *  - The nohup fallback captures spawn's *async* error event instead of crashing.
 */

describe('claudex-proxy constants', () => {
  it('pins the proxy endpoint to loopback :18765 (spec table)', () => {
    expect(CLAUDEX_PROXY_HOST).toBe('127.0.0.1');
    expect(CLAUDEX_PROXY_PORT).toBe(18765);
    expect(CLAUDEX_PROXY_URL).toBe('http://127.0.0.1:18765');
    expect(CLAUDEX_PROXY_BINARY).toBe('claude-code-proxy');
  });

  it('exposes the dedicated /healthz liveness endpoint (not the root path)', () => {
    expect(CLAUDEX_HEALTH_PATH).toBe('/healthz');
    expect(CLAUDEX_HEALTH_URL).toBe('http://127.0.0.1:18765/healthz');
  });

  it('builds the documented codex subcommand argv', () => {
    expect(buildAuthStatusArgs()).toEqual(['codex', 'auth', 'status']);
    expect(buildDeviceAuthArgs()).toEqual(['codex', 'auth', 'device']);
    expect(buildServeArgs()).toEqual(['serve', '--no-monitor']);
  });
});

describe('parseAuthStatus', () => {
  it('reports valid on exit 0 with an authenticated marker', () => {
    const s = parseAuthStatus({
      status: 0,
      stdout: 'Authenticated as user; token valid',
      stderr: '',
    });
    expect(s.state).toBe('valid');
  });

  it('reports expired when output mentions expiry', () => {
    const s = parseAuthStatus({ status: 0, stdout: 'Token expired 2 days ago', stderr: '' });
    expect(s.state).toBe('expired');
  });

  it('reports unauthenticated when output says not logged in', () => {
    const s = parseAuthStatus({
      status: 1,
      stdout: '',
      stderr: 'not authenticated: run codex auth device',
    });
    expect(s.state).toBe('unauthenticated');
  });

  it('reports unknown on an unrecognized non-zero exit', () => {
    const s = parseAuthStatus({ status: 2, stdout: 'weird', stderr: '' });
    expect(s.state).toBe('unknown');
  });

  it('does NOT trust a signal-terminated check (status null) even with an auth-looking line', () => {
    // status: null means the process was killed by a signal — an INCOMPLETE
    // check. An auth-looking line that happened to be flushed must not be read
    // as valid, or preflight passes on a check that never finished.
    const s = parseAuthStatus({ status: null, stdout: 'Authenticated', stderr: '' });
    expect(s.state).toBe('unknown');
  });

  it('extracts a best-effort expiry in days when present', () => {
    const s = parseAuthStatus({
      status: 0,
      stdout: 'Authenticated; expires in 9 days',
      stderr: '',
    });
    expect(s.state).toBe('valid');
    expect(s.expiresInDays).toBe(9);
  });

  it('treats a clean exit 0 with no explicit markers as valid', () => {
    const s = parseAuthStatus({ status: 0, stdout: 'Session active for account foo', stderr: '' });
    expect(s.state).toBe('valid');
    expect(s.expiresInDays).toBeUndefined();
  });

  it('NEVER retains token-shaped material from output', () => {
    const leaky = 'Authenticated. access_token=sk-abc123SECRETdeadbeef refresh_token=rt-9999';
    const s: AuthStatus = parseAuthStatus({ status: 0, stdout: leaky, stderr: '' });
    const serialized = JSON.stringify(s);
    expect(serialized).not.toContain('sk-abc123SECRETdeadbeef');
    expect(serialized).not.toContain('rt-9999');
    expect(serialized).not.toContain('access_token');
    expect(serialized).not.toContain('refresh_token');
  });
});

describe('checkAuthStatus', () => {
  it('runs the status subcommand and parses the result', () => {
    const run = vi.fn(
      (_cmd: string, _args: string[]): ProxyRunResult => ({
        status: 0,
        stdout: 'Authenticated; expires in 7 days',
        stderr: '',
      }),
    );
    const s = checkAuthStatus(run);
    expect(run).toHaveBeenCalledWith(CLAUDEX_PROXY_BINARY, ['codex', 'auth', 'status']);
    expect(s.state).toBe('valid');
    expect(s.expiresInDays).toBe(7);
  });

  it('surfaces unknown when the default runner cannot find the binary', () => {
    // Exercises the default spawnSync path against an absent binary: no throw,
    // status is non-zero/null → unknown. Deterministic on a box without the proxy.
    const s = checkAuthStatus();
    expect(['unknown', 'unauthenticated', 'valid', 'expired']).toContain(s.state);
  });
});

describe('runDeviceReauth', () => {
  it('spawns the device flow with inherited stdio (never captures the code/token)', () => {
    const calls: Array<{ cmd: string; args: string[]; opts: { stdio: string } }> = [];
    const status = runDeviceReauth((cmd, args, opts) => {
      calls.push({ cmd, args, opts });
      return { status: 0 };
    });
    expect(status).toBe(0);
    expect(calls).toHaveLength(1);
    expect(calls[0]!.cmd).toBe(CLAUDEX_PROXY_BINARY);
    expect(calls[0]!.args).toEqual(['codex', 'auth', 'device']);
    // stdio 'inherit' is the security-critical bit: the device code streams to
    // the user's TTY; the launcher never pipes/captures it.
    expect(calls[0]!.opts.stdio).toBe('inherit');
  });

  it('returns 1 when the child yields no status (absent binary)', () => {
    const status = runDeviceReauth(() => ({ status: null }));
    expect(status).toBe(1);
  });
});

describe('checkProxyBinary', () => {
  it('resolves via the default `which` path (proxy absent → null)', () => {
    // Covers the default resolver; on CI/dev the proxy is not installed.
    const r = checkProxyBinary();
    expect(typeof r.present).toBe('boolean');
    if (!r.present) expect(r.path).toBeNull();
  });

  it('reports present with the resolved path', () => {
    const r = checkProxyBinary(() => '/home/u/.local/bin/claude-code-proxy');
    expect(r.present).toBe(true);
    expect(r.path).toBe('/home/u/.local/bin/claude-code-proxy');
  });

  it('reports absent when the resolver finds nothing', () => {
    const r = checkProxyBinary(() => null);
    expect(r.present).toBe(false);
    expect(r.path).toBeNull();
  });
});

describe('probeLiveness (proxy-specific /healthz, not arbitrary HTTP)', () => {
  it('defaults to probing the /healthz endpoint, never the root path', async () => {
    const seen: string[] = [];
    await probeLiveness(undefined, async (u) => {
      seen.push(u);
      return { status: 200 };
    });
    expect(seen[0]).toBe(CLAUDEX_HEALTH_URL);
    expect(seen[0]).toContain('/healthz');
  });

  it('treats a 200 on /healthz as alive', async () => {
    const live = await probeLiveness(CLAUDEX_HEALTH_URL, async () => ({ status: 200 }));
    expect(live).toBe(true);
  });

  it('treats a 204 on /healthz as alive', async () => {
    const live = await probeLiveness(CLAUDEX_HEALTH_URL, async () => ({ status: 204 }));
    expect(live).toBe(true);
  });

  it('treats a 404 as DEAD — does not trust an arbitrary responder on the port (CWE-345)', async () => {
    // The whole point: a random local process squatting :18765 will not honor the
    // proxy's /healthz contract, so a non-2xx there must not be mistaken for the proxy.
    const live = await probeLiveness(CLAUDEX_HEALTH_URL, async () => ({ status: 404 }));
    expect(live).toBe(false);
  });

  it('treats a 500 as DEAD (unhealthy / not the proxy health contract)', async () => {
    const live = await probeLiveness(CLAUDEX_HEALTH_URL, async () => ({ status: 500 }));
    expect(live).toBe(false);
  });

  it('treats a missing status as dead', async () => {
    const live = await probeLiveness(CLAUDEX_HEALTH_URL, async () => ({}));
    expect(live).toBe(false);
  });

  it('treats a connection failure (reject) as dead', async () => {
    const live = await probeLiveness(CLAUDEX_HEALTH_URL, async () => {
      throw new Error('ECONNREFUSED');
    });
    expect(live).toBe(false);
  });

  it('treats a timeout as dead', async () => {
    const never = () => new Promise<{ status?: number }>(() => {});
    const live = await probeLiveness(CLAUDEX_HEALTH_URL, never, 20);
    expect(live).toBe(false);
  });
});

describe('buildSystemdUnitContent', () => {
  it('emits a user unit that execs the given binary with serve args', () => {
    const unit = buildSystemdUnitContent('/home/u/.local/bin/claude-code-proxy');
    expect(unit).toContain('[Unit]');
    expect(unit).toContain('[Service]');
    expect(unit).toContain('[Install]');
    expect(unit).toContain('/home/u/.local/bin/claude-code-proxy serve --no-monitor');
    expect(unit).toContain('WantedBy=default.target');
  });

  it('never embeds credential material', () => {
    const unit = buildSystemdUnitContent('/home/u/.local/bin/claude-code-proxy');
    expect(unit).not.toMatch(/token/i);
    expect(unit).not.toMatch(/auth\.json/i);
  });

  it('rejects a path containing a newline (CWE-74 systemd directive injection)', () => {
    // A raw newline in ExecStart would let an attacker append arbitrary unit
    // directives — e.g. `ExecStartPost=curl evil`. Must be rejected outright.
    expect(() =>
      buildSystemdUnitContent('/bin/claude-code-proxy\nExecStartPost=/bin/rm -rf /'),
    ).toThrow();
  });

  it('rejects a path containing a carriage return', () => {
    expect(() => buildSystemdUnitContent('/bin/claude-code-proxy\rmalicious')).toThrow();
  });

  it('rejects a path with other control characters', () => {
    expect(() => buildSystemdUnitContent('/bin/claude-code-proxy\x00nul')).toThrow();
  });

  it('rejects a non-absolute path', () => {
    expect(() => buildSystemdUnitContent('claude-code-proxy')).toThrow();
    expect(() => buildSystemdUnitContent('')).toThrow();
  });

  it('systemd-quotes a path that contains spaces', () => {
    const unit = buildSystemdUnitContent('/home/u/my apps/claude-code-proxy');
    expect(unit).toContain('ExecStart="/home/u/my apps/claude-code-proxy" serve --no-monitor');
  });

  it('escapes embedded quotes and backslashes when quoting', () => {
    const unit = buildSystemdUnitContent('/home/u/we"ird\\dir/claude-code-proxy');
    // No unescaped closing quote can terminate the token early.
    expect(unit).toContain('ExecStart="/home/u/we\\"ird\\\\dir/claude-code-proxy" serve');
  });

  it('leaves a clean absolute path unquoted (no needless churn)', () => {
    const unit = buildSystemdUnitContent('/home/u/.local/bin/claude-code-proxy');
    expect(unit).toContain('ExecStart=/home/u/.local/bin/claude-code-proxy serve --no-monitor');
  });
});

describe('systemdUnitPath', () => {
  it('targets the systemd --user unit dir', () => {
    expect(systemdUnitPath('/home/u')).toBe(
      '/home/u/.config/systemd/user/claude-code-proxy.service',
    );
  });
});

describe('installSystemdUnit', () => {
  it('writes the unit and returns true when daemon-reload succeeds', () => {
    let written: { path: string; content: string } | null = null;
    const ok = installSystemdUnit('/bin/claude-code-proxy', {
      home: '/home/u',
      writeUnit: (path, content) => {
        written = { path, content };
      },
      run: () => ({ status: 0, stdout: '', stderr: '' }),
    });
    expect(ok).toBe(true);
    expect(written).not.toBeNull();
    expect(written!.path).toBe('/home/u/.config/systemd/user/claude-code-proxy.service');
    expect(written!.content).toContain('ExecStart=/bin/claude-code-proxy serve --no-monitor');
  });

  it('returns false when daemon-reload fails (systemd --user unavailable)', () => {
    const ok = installSystemdUnit('/bin/claude-code-proxy', {
      home: '/home/u',
      writeUnit: () => {},
      run: () => ({ status: 1, stdout: '', stderr: 'Failed to connect to bus' }),
    });
    expect(ok).toBe(false);
  });

  it('returns false when writing the unit throws', () => {
    const ok = installSystemdUnit('/bin/claude-code-proxy', {
      home: '/home/u',
      writeUnit: () => {
        throw new Error('EACCES');
      },
      run: () => ({ status: 0, stdout: '', stderr: '' }),
    });
    expect(ok).toBe(false);
  });

  it('refuses to write a unit for an injection-bearing path (never writes a poisoned unit)', () => {
    const writeUnit = vi.fn();
    const ok = installSystemdUnit('/bin/claude-code-proxy\nExecStartPost=/bin/rm -rf /', {
      home: '/home/u',
      writeUnit,
      run: () => ({ status: 0, stdout: '', stderr: '' }),
    });
    expect(ok).toBe(false);
    // The poisoned unit content is never even produced, so nothing is written.
    expect(writeUnit).not.toHaveBeenCalled();
  });

  it('writes to a real temp dir via the default writer', () => {
    const home = mkdtempSync(join(tmpdir(), 'claudex-unit-'));
    try {
      const ok = installSystemdUnit('/bin/claude-code-proxy', {
        home,
        run: () => ({ status: 0, stdout: '', stderr: '' }),
      });
      expect(ok).toBe(true);
      const written = readFileSync(systemdUnitPath(home), 'utf8');
      expect(written).toContain('[Service]');
    } finally {
      rmSync(home, { recursive: true, force: true });
    }
  });
});

describe('runProxyPreflight', () => {
  const trustedListener = () => 'ok' as const;

  it('is ok when binary present, auth valid, proxy live, and listener identity-verified', async () => {
    const report = await runProxyPreflight({
      checkBinary: () => ({ present: true, path: '/bin/claude-code-proxy' }),
      checkAuth: () => ({ state: 'valid' }),
      probe: async () => true,
      verifyListener: trustedListener,
    });
    expect(report.ok).toBe(true);
    expect(report.listenerVerdict).toBe('ok');
    expect(report.problems).toEqual([]);
  });

  it('flags a missing binary', async () => {
    const report = await runProxyPreflight({
      checkBinary: () => ({ present: false, path: null }),
      checkAuth: () => ({ state: 'valid' }),
      probe: async () => true,
      verifyListener: trustedListener,
    });
    expect(report.ok).toBe(false);
    expect(report.problems.some((p) => /binary/i.test(p))).toBe(true);
  });

  it('flags expired auth (re-auth needed)', async () => {
    const report = await runProxyPreflight({
      checkBinary: () => ({ present: true, path: '/bin/claude-code-proxy' }),
      checkAuth: () => ({ state: 'expired' }),
      probe: async () => true,
      verifyListener: trustedListener,
    });
    expect(report.ok).toBe(false);
    expect(report.needsReauth).toBe(true);
    expect(report.problems.some((p) => /auth/i.test(p))).toBe(true);
  });

  it('flags a dead proxy', async () => {
    const report = await runProxyPreflight({
      checkBinary: () => ({ present: true, path: '/bin/claude-code-proxy' }),
      checkAuth: () => ({ state: 'valid' }),
      probe: async () => false,
      verifyListener: trustedListener,
    });
    expect(report.ok).toBe(false);
    expect(report.live).toBe(false);
  });

  it('flags an unknown auth state without marking it for re-auth', async () => {
    const report = await runProxyPreflight({
      checkBinary: () => ({ present: true, path: '/bin/claude-code-proxy' }),
      checkAuth: () => ({ state: 'unknown' }),
      probe: async () => true,
      verifyListener: trustedListener,
    });
    expect(report.ok).toBe(false);
    expect(report.needsReauth).toBe(false);
    expect(report.problems.some((p) => /could not determine/i.test(p))).toBe(true);
  });

  it('does NOT pass preflight when the live responder fails identity verification (F2b)', async () => {
    // A squatter answering /healthz-2xx must not yield ok:true just because the
    // binary is installed and OAuth is valid — the identity gate holds here too.
    for (const verdict of ['foreign-user', 'wrong-exe', 'unknown'] as const) {
      const report = await runProxyPreflight({
        checkBinary: () => ({ present: true, path: '/bin/claude-code-proxy' }),
        checkAuth: () => ({ state: 'valid' }),
        probe: async () => true,
        verifyListener: () => verdict,
      });
      expect(report.ok).toBe(false);
      expect(report.live).toBe(true);
      expect(report.listenerVerdict).toBe(verdict);
      expect(report.problems.some((p) => /identity could not be verified/i.test(p))).toBe(true);
      // The identity problem is non-sensitive: port + verdict only, no token.
      expect(JSON.stringify(report)).not.toMatch(/token|sk-|auth\.json/i);
    }
  });

  it('does not verify listener identity when the proxy is dead (no listener to trust)', async () => {
    const verifyListener = vi.fn(() => 'ok' as const);
    const report = await runProxyPreflight({
      checkBinary: () => ({ present: true, path: '/bin/claude-code-proxy' }),
      checkAuth: () => ({ state: 'valid' }),
      probe: async () => false,
      verifyListener,
    });
    expect(verifyListener).not.toHaveBeenCalled();
    expect(report.listenerVerdict).toBe('unknown');
    expect(report.ok).toBe(false);
  });

  it('does not leak token material for any auth state', async () => {
    const report = await runProxyPreflight({
      checkBinary: () => ({ present: true, path: '/bin/claude-code-proxy' }),
      checkAuth: () => ({ state: 'expired' }),
      probe: async () => false,
      verifyListener: trustedListener,
    });
    expect(JSON.stringify(report)).not.toMatch(/token|sk-|auth\.json/i);
  });

  it('runs end-to-end with all real defaults (no proxy installed → not ok)', async () => {
    // Exercises the default checkBinary/checkAuth/probe closures against a box
    // with no proxy: absent binary, spawnSync status, real loopback probe that
    // fast-fails with ECONNREFUSED. Asserts shape only (never token material).
    const report = await runProxyPreflight();
    expect(typeof report.ok).toBe('boolean');
    expect(Array.isArray(report.problems)).toBe(true);
    expect(['valid', 'expired', 'unauthenticated', 'unknown']).toContain(report.auth.state);
    expect(JSON.stringify(report)).not.toMatch(/access_token|refresh_token|sk-/i);
  });
});

/**
 * A minimal fake ChildProcess for the nohup-fallback tests: records once()
 * handlers so a test can drive the async 'spawn'/'error' events, and tracks
 * whether the 'error' listener was already attached at the moment unref() ran
 * (the security-critical ordering from finding #1).
 */
function fakeChild() {
  const handlers: Record<string, (arg?: unknown) => void> = {};
  const state = { unreffed: false, errorHandlerAtUnref: false };
  const child = {
    once(event: string, listener: (arg?: unknown) => void) {
      handlers[event] = listener;
      return child;
    },
    unref() {
      state.unreffed = true;
      state.errorHandlerAtUnref = typeof handlers.error === 'function';
    },
    emit(event: string, arg?: unknown) {
      handlers[event]?.(arg);
    },
  };
  return {
    child: child as unknown as SpawnedChild & { emit(e: string, a?: unknown): void },
    state,
  };
}

describe('startNohupProxy (finding #1 — async spawn error must not crash)', () => {
  it('resolves status 0 only after a confirmed spawn, and unrefs the child', async () => {
    const { child, state } = fakeChild();
    const spawnImpl = vi.fn((_cmd: string, _args: string[]) => {
      queueMicrotask(() => child.emit('spawn'));
      return child;
    });
    const r = await startNohupProxy({ resolveBin: () => '/bin/claude-code-proxy', spawnImpl });
    expect(r.status).toBe(0);
    expect(state.unreffed).toBe(true);
    // The error listener MUST be registered before unref(), so an ENOENT that
    // arrives asynchronously can never become an unhandled 'error' crash.
    expect(state.errorHandlerAtUnref).toBe(true);
    expect(spawnImpl).toHaveBeenCalledWith('/bin/claude-code-proxy', ['serve', '--no-monitor'], {
      detached: true,
      stdio: 'ignore',
    });
  });

  it('captures an async spawn error (ENOENT) as a failed start instead of crashing', async () => {
    const { child, state } = fakeChild();
    const spawnImpl = () => {
      queueMicrotask(() => child.emit('error', new Error('spawn claude-code-proxy ENOENT')));
      return child;
    };
    const r = await startNohupProxy({ resolveBin: () => '/bin/claude-code-proxy', spawnImpl });
    expect(r.status).toBe(1);
    expect(r.stderr).toContain('ENOENT');
    expect(state.unreffed).toBe(false); // never unref a child that failed to start
  });

  it('captures a synchronous spawn throw as a failed start', async () => {
    const spawnImpl = () => {
      throw new Error('EACCES');
    };
    const r = await startNohupProxy({ resolveBin: () => '/bin/claude-code-proxy', spawnImpl });
    expect(r.status).toBe(1);
    expect(r.stderr).toContain('EACCES');
  });

  it('ignores a late error after a successful spawn (settles once)', async () => {
    const { child } = fakeChild();
    const spawnImpl = () => {
      queueMicrotask(() => {
        child.emit('spawn');
        child.emit('error', new Error('late boom'));
      });
      return child;
    };
    const r = await startNohupProxy({ resolveBin: () => '/bin/claude-code-proxy', spawnImpl });
    expect(r.status).toBe(0); // first settle wins; the late error cannot flip it
  });
});

describe('verifyListenerIdentity (finding #2 — OS-level listener identity, CWE-345)', () => {
  const me: ListenerIdentity = {
    pid: 4242,
    uid: 1000,
    exePath: '/home/me/.local/bin/claude-code-proxy',
  };
  // Identity canonicalize for tests: fake paths don't exist on disk, so we map
  // each path to itself and exercise symlink resolution explicitly where needed.
  const idc = (p: string) => p;

  it('accepts a listener owned by the current uid whose exe is the expected proxy path', () => {
    const verdict = verifyListenerIdentity({
      identify: () => me,
      currentUid: () => 1000,
      expectedExe: () => '/home/me/.local/bin/claude-code-proxy',
      canonicalize: idc,
    });
    expect(verdict).toBe('ok');
  });

  it('resolves symlinks on BOTH sides before comparing (canonical match → ok)', () => {
    // The listener exe and our resolved binary reach the same real file via
    // different symlink paths — a canonical comparison must accept it.
    const canon: Record<string, string> = {
      '/var/run/proxy.link': '/opt/proxy/bin/claude-code-proxy',
      '/home/me/.local/bin/claude-code-proxy': '/opt/proxy/bin/claude-code-proxy',
    };
    const verdict = verifyListenerIdentity({
      identify: () => ({ ...me, exePath: '/var/run/proxy.link' }),
      currentUid: () => 1000,
      expectedExe: () => '/home/me/.local/bin/claude-code-proxy',
      canonicalize: (p) => canon[p] ?? null,
    });
    expect(verdict).toBe('ok');
  });

  it('does NOT trust a same-uid process at the WRONG path with the right basename (F2a)', () => {
    // The squatter vector on a shared-uid host: right basename, wrong path. The
    // basename must NEVER be a trust signal when an expected exact path resolved.
    const verdict = verifyListenerIdentity({
      identify: () => ({ ...me, exePath: '/tmp/claude-code-proxy' }),
      currentUid: () => 1000,
      expectedExe: () => '/home/me/.local/bin/claude-code-proxy',
      canonicalize: idc,
    });
    expect(verdict).toBe('wrong-exe');
  });

  it('fails closed (unknown) when our own proxy binary path cannot be resolved (F2a)', () => {
    // No expected path → we cannot assert identity → refuse to trust (no basename
    // acceptance). Previously this returned `ok` by basename; that was a bypass.
    const verdict = verifyListenerIdentity({
      identify: () => me,
      currentUid: () => 1000,
      expectedExe: () => null,
      canonicalize: idc,
    });
    expect(verdict).toBe('unknown');
  });

  it('fails closed (unknown) when a path cannot be canonicalized (F2a)', () => {
    const verdict = verifyListenerIdentity({
      identify: () => me,
      currentUid: () => 1000,
      expectedExe: () => '/home/me/.local/bin/claude-code-proxy',
      canonicalize: () => null, // e.g. binary deleted out from under the listener
    });
    expect(verdict).toBe('unknown');
  });

  it('rejects a listener owned by a DIFFERENT uid (foreign-user) — fail closed', () => {
    const verdict = verifyListenerIdentity({
      identify: () => ({ ...me, uid: 0 }),
      currentUid: () => 1000,
      expectedExe: () => '/home/me/.local/bin/claude-code-proxy',
      canonicalize: idc,
    });
    expect(verdict).toBe('foreign-user');
  });

  it('rejects a same-user listener whose exe is NOT the proxy (wrong-exe)', () => {
    const verdict = verifyListenerIdentity({
      identify: () => ({ ...me, exePath: '/usr/bin/nc' }),
      currentUid: () => 1000,
      expectedExe: () => '/home/me/.local/bin/claude-code-proxy',
      canonicalize: idc,
    });
    expect(verdict).toBe('wrong-exe');
  });

  it('returns unknown (fail closed) when the listener cannot be identified', () => {
    const verdict = verifyListenerIdentity({
      identify: () => null,
      currentUid: () => 1000,
      expectedExe: () => '/home/me/.local/bin/claude-code-proxy',
      canonicalize: idc,
    });
    expect(verdict).toBe('unknown');
  });

  it('returns unknown when the current uid is unavailable (non-posix)', () => {
    const verdict = verifyListenerIdentity({
      identify: () => me,
      currentUid: () => -1,
      expectedExe: () => '/home/me/.local/bin/claude-code-proxy',
      canonicalize: idc,
    });
    expect(verdict).toBe('unknown');
  });

  it('returns unknown when the listener exe path cannot be read', () => {
    const verdict = verifyListenerIdentity({
      identify: () => ({ ...me, exePath: null }),
      currentUid: () => 1000,
      expectedExe: () => '/home/me/.local/bin/claude-code-proxy',
      canonicalize: idc,
    });
    expect(verdict).toBe('unknown');
  });

  it('runs with real defaults without throwing (identity may be unresolved → verdict)', () => {
    const verdict = verifyListenerIdentity();
    expect(['ok', 'foreign-user', 'wrong-exe', 'unknown']).toContain(verdict);
  });
});

describe('ensureProxyRunning', () => {
  const ok: ProxyRunResult = { status: 0, stdout: '', stderr: '' };
  const nohupOk = async (): Promise<ProxyRunResult> => ok;
  const trusted = () => 'ok' as const;

  it('is a no-op when the proxy is already live AND identity-verified', async () => {
    const startSystemd = vi.fn(() => ok);
    const startNohup = vi.fn(nohupOk);
    const r = await ensureProxyRunning({
      probe: async () => true,
      verifyListener: trusted,
      startSystemd,
      startNohup,
      waitMs: async () => {},
    });
    expect(r.method).toBe('already');
    expect(r.live).toBe(true);
    expect(startSystemd).not.toHaveBeenCalled();
    expect(startNohup).not.toHaveBeenCalled();
  });

  it('fails closed as untrusted when a responder holds :18765 but identity is NOT ours', async () => {
    // A foreign process answers /healthz but the listener is not our proxy
    // (foreign uid / wrong exe / unidentifiable). We must NOT trust it and must
    // NOT start a second proxy (the port is already taken) — fail closed.
    const startSystemd = vi.fn(() => ok);
    const startNohup = vi.fn(nohupOk);
    const r = await ensureProxyRunning({
      probe: async () => true,
      verifyListener: () => 'foreign-user',
      startSystemd,
      startNohup,
      waitMs: async () => {},
    });
    expect(r.method).toBe('untrusted');
    expect(r.live).toBe(false);
    expect(startSystemd).not.toHaveBeenCalled();
    expect(startNohup).not.toHaveBeenCalled();
  });

  it('starts via systemd when available and then becomes trusted-live', async () => {
    let calls = 0;
    const r = await ensureProxyRunning({
      probe: async () => calls++ > 0, // dead first, live after start
      verifyListener: trusted,
      startSystemd: () => ok,
      startNohup: async () => {
        throw new Error('should not fall back');
      },
      waitMs: async () => {},
    });
    expect(r.method).toBe('systemd');
    expect(r.live).toBe(true);
  });

  it('waits past a slow systemd bind before giving up (finding #2 — no duplicate proxy)', async () => {
    // systemd `start` returns 0 (job accepted) but the socket only binds on the
    // 4th probe — still well within the startup deadline. nohup must NOT run,
    // or two proxies would contend for :18765.
    let probes = 0;
    const startNohup = vi.fn(nohupOk);
    const r = await ensureProxyRunning({
      probe: async () => probes++ >= 3,
      verifyListener: trusted,
      startSystemd: () => ok,
      startNohup,
      waitMs: async () => {},
      settleMs: 10,
      startupDeadlineMs: 200,
    });
    expect(r.method).toBe('systemd');
    expect(r.live).toBe(true);
    expect(startNohup).not.toHaveBeenCalled();
  });

  it('does NOT fall back to nohup after systemd accepts but never binds (finding #1 — dup-proxy race)', async () => {
    // systemctl start exit 0 means the job was ACCEPTED, not bound. If it binds
    // just after our deadline (or systemd restarts it), a nohup fallback would
    // create a SECOND proxy contending for :18765. Once systemd has accepted the
    // job we never spawn nohup — we report a managed-service startup failure.
    const startNohup = vi.fn(nohupOk);
    const r = await ensureProxyRunning({
      probe: async () => false, // never becomes live within the deadline
      verifyListener: trusted,
      startSystemd: () => ok,
      startNohup,
      waitMs: async () => {},
      settleMs: 10,
      startupDeadlineMs: 30,
    });
    expect(startNohup).not.toHaveBeenCalled();
    expect(r.method).toBe('failed');
    expect(r.live).toBe(false);
  });

  it('does NOT trust a systemd-started responder whose identity cannot be verified', async () => {
    // Dead at first (so we reach the systemd start), then the socket binds — but
    // identity never verifies (e.g. a squatter beat systemd to the port). A live
    // responder that fails identity must never be reported as a successful start.
    let calls = 0;
    const startNohup = vi.fn(nohupOk);
    const r = await ensureProxyRunning({
      probe: async () => calls++ > 0,
      verifyListener: () => 'wrong-exe',
      startSystemd: () => ok,
      startNohup,
      waitMs: async () => {},
      settleMs: 10,
      startupDeadlineMs: 30,
    });
    expect(startNohup).not.toHaveBeenCalled();
    expect(r.method).toBe('failed');
    expect(r.live).toBe(false);
  });

  it('falls back to nohup only when systemd start FAILS outright (not accepted)', async () => {
    let calls = 0;
    const r = await ensureProxyRunning({
      // A failed systemd start skips its post-start poll, so probes are:
      // #0 initial (dead), #1 after nohup (live). nohup fallback is reachable
      // ONLY because systemd never accepted the job (status 1).
      probe: async () => calls++ > 0,
      verifyListener: trusted,
      startSystemd: () => ({ status: 1, stdout: '', stderr: 'no systemd' }),
      startNohup: nohupOk,
      waitMs: async () => {},
      settleMs: 10,
      startupDeadlineMs: 30,
    });
    expect(r.method).toBe('nohup');
    expect(r.live).toBe(true);
  });

  it('does NOT trust a nohup-started responder whose identity cannot be verified', async () => {
    let calls = 0;
    const r = await ensureProxyRunning({
      probe: async () => calls++ > 0,
      verifyListener: () => 'unknown',
      startSystemd: () => ({ status: 1, stdout: '', stderr: 'no systemd' }),
      startNohup: nohupOk,
      waitMs: async () => {},
      settleMs: 10,
      startupDeadlineMs: 30,
    });
    expect(r.method).toBe('failed');
    expect(r.live).toBe(false);
  });

  it('reports failed when nothing brings the proxy up', async () => {
    const r = await ensureProxyRunning({
      probe: async () => false,
      verifyListener: trusted,
      startSystemd: () => ({ status: 1, stdout: '', stderr: '' }),
      startNohup: async () => ({ status: 1, stdout: '', stderr: '' }),
      waitMs: async () => {},
      settleMs: 10,
      startupDeadlineMs: 30,
    });
    expect(r.method).toBe('failed');
    expect(r.live).toBe(false);
  });
});
