'use strict';

const { execFile: execFileCb, spawn: spawnCb } = require('child_process');
const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const { atomicWriteFileSync } = require('../atomic-write');
const { requestOrigin } = require('./transport-security');

const DEVTUNNEL_URL_RE = /https:\/\/[A-Za-z0-9.-]+\.devtunnels\.ms(?::\d+)?\/?/g;
const HTTP_URL_RE = /https?:\/\/[^\s<>"')]+/g;
const SENSITIVE_QUERY_KEYS = new Set(['claim', 'secret', 'token', 'ctm_token', 'code', 'state']);

const trafficEntries = [];
const MAX_TRAFFIC_ENTRIES = 80;
const LOG_TAIL_BYTES = 24000;
const LOGIN_REUSE_MS = 8 * 60 * 1000;
const HOST_READY_TIMEOUT_MS = 45000;
const WATCHDOG_CHECK_INTERVAL_MS = 30000;
const WATCHDOG_WAKE_DRIFT_MS = 90000;
const PUBLIC_PROBE_TIMEOUT_MS = 6000;
const DEVTUNNEL_MAX_EXPIRATION = '30d';
const DEVTUNNEL_RENEWAL_INTERVAL_MS = 25 * 24 * 60 * 60 * 1000;
const HOST_HEADER_MODE_PASSTHROUGH = 'passthrough';
const HOST_HEADER_MODE_DEFAULT = 'default';

function defaultExecFile(file, args, options = {}) {
  return new Promise((resolve, reject) => {
    execFileCb(file, args, options, (err, stdout, stderr) => {
      if (err) {
        err.stdout = stdout;
        err.stderr = stderr;
        reject(err);
        return;
      }
      resolve({ stdout, stderr });
    });
  });
}

function defaultSpawn(file, args, options = {}) {
  const child = spawnCb(file, args, options);
  if (typeof child.unref === 'function') child.unref();
  return child;
}

function shellQuote(value) {
  const s = String(value || '');
  if (/^[A-Za-z0-9_./:@%+=,-]+$/.test(s)) return s;
  return `'${s.replace(/'/g, `'\\''`)}'`;
}

function command(file, args) {
  const argv = [file, ...args];
  return { argv, display: argv.map(shellQuote).join(' ') };
}

function normalizeLoginProvider(input = {}) {
  const raw = String(input.provider || '').trim().toLowerCase();
  if (raw === 'microsoft' || raw === 'entra' || raw === 'aad') return 'microsoft';
  if (raw === 'github' || input.github === true) return 'github';
  return 'github';
}

function loginProviderArgs(provider) {
  return provider === 'github' ? ['-g'] : ['-e'];
}

function loginProviderLabel(provider) {
  return provider === 'github' ? 'GitHub' : 'Microsoft';
}

// Host-event diagnostics: classify devtunnel host output so the Access page can
// show WHY the phone link dropped (credential expiry vs relay disconnect vs
// recovery) instead of a generic failure.
const HOST_EVENT_LIMIT = 30;
const HOST_EVENT_REPEAT_SUPPRESS_MS = 30 * 1000;

function classifyDevTunnelHostEventText(text) {
  const t = String(text || '');
  if (!t.trim()) return null;
  if (/unauthoriz|forbidden|authentication failed|login\s+required|token[^\n]{0,60}(expired|invalid|refresh)/i.test(t)) {
    return 'auth_failure';
  }
  if (/connection\s*lost|session closed/i.test(t)) return 'connection_lost';
  if (/relay restored|reconnected/i.test(t)) return 'reconnected';
  return null;
}

function appendManagedTunnelHostEvent(event, options = {}) {
  if (!event || !event.type) return null;
  try {
    const state = loadManagedTunnelState(options);
    if (!state || !state.tunnel_id) return null;
    const events = Array.isArray(state.host_events) ? state.host_events : [];
    const at = new Date().toISOString();
    const last = events.length ? events[events.length - 1] : null;
    const suppressMs = Number(options.hostEventRepeatSuppressMs || HOST_EVENT_REPEAT_SUPPRESS_MS);
    if (last && last.type === event.type && (Date.parse(at) - (Date.parse(last.at) || 0)) < suppressMs) {
      return null;
    }
    const entry = { at, type: String(event.type), detail: String(event.detail || '').slice(0, 240) };
    state.host_events = [...events, entry].slice(-HOST_EVENT_LIMIT);
    writeManagedTunnelState(state, options);
    return entry;
  } catch {
    return null;
  }
}

// Only the CTM process that spawned the host sees its pipes; after a CTM restart
// the re-adopted host runs unobserved until its next (re)start.
function watchDevTunnelHostOutput(child, options = {}) {
  let carry = '';
  function scan(chunk) {
    const text = carry + String(chunk || '');
    carry = text.slice(-200);
    const type = classifyDevTunnelHostEventText(text);
    if (type) appendManagedTunnelHostEvent({ type, detail: text.trim().slice(-240) }, options);
  }
  if (child && child.stdout) child.stdout.on('data', scan);
  if (child && child.stderr) child.stderr.on('data', scan);
}

function setupDir(options = {}) {
  const configDir = path.resolve(options.configDir || path.join(process.env.HOME || process.cwd(), '.walle', 'data'));
  return path.join(configDir, 'microsoft-dev-tunnel');
}

function managedStatePath(options = {}) {
  return path.join(setupDir(options), 'managed-tunnel.json');
}

function loginStatePath(options = {}) {
  return path.join(setupDir(options), 'login-process.json');
}

function keepAwakeStatePath(options = {}) {
  return path.join(setupDir(options), 'keep-awake.json');
}

function installStatePath(options = {}) {
  return path.join(setupDir(options), 'install-process.json');
}

function logsDir(options = {}) {
  const configDir = path.resolve(options.configDir || path.join(process.env.HOME || process.cwd(), '.walle', 'data'));
  return path.join(configDir, 'logs');
}

function readJsonFile(filePath, fsImpl = fs) {
  try {
    const parsed = JSON.parse(fsImpl.readFileSync(filePath, 'utf8'));
    return parsed && typeof parsed === 'object' ? parsed : null;
  } catch {
    return null;
  }
}

function writeJsonFile(filePath, value, options = {}) {
  const fsImpl = options.fs || fs;
  fsImpl.mkdirSync(path.dirname(filePath), { recursive: true, mode: 0o700 });
  try { fsImpl.chmodSync(path.dirname(filePath), 0o700); } catch {}
  const body = JSON.stringify(value, null, 2) + '\n';
  if (options.atomicWriteFileSync || fsImpl === fs) {
    (options.atomicWriteFileSync || atomicWriteFileSync)(filePath, body, { mode: 0o600 });
  } else {
    fsImpl.writeFileSync(filePath, body, { mode: 0o600 });
  }
  try { fsImpl.chmodSync(filePath, 0o600); } catch {}
}

function loadManagedTunnelState(options = {}) {
  return readJsonFile(managedStatePath(options), options.fs || fs);
}

function writeManagedTunnelState(state, options = {}) {
  writeJsonFile(managedStatePath(options), { version: 1, ...state }, options);
}

function loadLoginProcessState(options = {}) {
  return readJsonFile(loginStatePath(options), options.fs || fs);
}

function writeLoginProcessState(state, options = {}) {
  writeJsonFile(loginStatePath(options), { version: 1, ...state }, options);
}

function loadInstallProcessState(options = {}) {
  return readJsonFile(installStatePath(options), options.fs || fs);
}

function writeInstallProcessState(state, options = {}) {
  writeJsonFile(installStatePath(options), { version: 1, ...state }, options);
}

function loadKeepAwakeState(options = {}) {
  return readJsonFile(keepAwakeStatePath(options), options.fs || fs);
}

function writeKeepAwakeState(state, options = {}) {
  writeJsonFile(keepAwakeStatePath(options), { version: 1, ...state }, options);
}

function pidIsRunning(pid) {
  const n = Number(pid);
  if (!Number.isFinite(n) || n <= 0) return false;
  try {
    process.kill(n, 0);
    return true;
  } catch (err) {
    return err && err.code === 'EPERM';
  }
}

function managedTunnelDesiredRunning(state = {}) {
  if (!state || typeof state !== 'object') return false;
  if (state.desired_running === true) return true;
  if (state.desired_running === false) return false;
  if (state.stopped_at) return false;
  return !!(state.tunnel_id && state.origin);
}

function commandLooksLikeDevTunnelHost(commandLine, tunnelId) {
  const body = String(commandLine || '');
  const id = normalizeTunnelId(tunnelId || '');
  if (!id || !body) return false;
  return /(?:^|[\/\s])devtunnel(?:\s|$)/.test(body)
    && /(?:^|\s)host(?:\s|$)/.test(body)
    && body.includes(id);
}

function commandHasHeaderPassthrough(commandLine) {
  const body = String(commandLine || '');
  return /--host-header(?:=|\s+)unchanged(?:\s|$)/.test(body)
    && /--origin-header(?:=|\s+)unchanged(?:\s|$)/.test(body);
}

function normalizeHostHeaderMode(value) {
  const raw = String(value || '').trim().toLowerCase();
  if (raw === HOST_HEADER_MODE_DEFAULT || raw === 'default_headers' || raw === 'rewritten') return HOST_HEADER_MODE_DEFAULT;
  return HOST_HEADER_MODE_PASSTHROUGH;
}

function managedTunnelAcceptsDefaultHostHeaders(state = {}) {
  return normalizeHostHeaderMode(state.host_header_mode || state.header_mode) === HOST_HEADER_MODE_DEFAULT;
}

function managedTunnelProcessUsable(processInfo = {}, state = {}) {
  return !!(processInfo && processInfo.running)
    && (!!processInfo.header_passthrough || managedTunnelAcceptsDefaultHostHeaders(state));
}

function hostStartFailureText(err) {
  return String([
    err?.message || '',
    err?.host_log_tail || '',
    err?.stdout || '',
    err?.stderr || '',
  ].filter(Boolean).join('\n'));
}

function isHeaderPassthroughHostFailure(err) {
  const text = hostStartFailureText(err);
  return /same\s+key\s+has\s+already\s+been\s+added[\s\S]*key:\s*host/i.test(text)
    || /an\s+item\s+with\s+the\s+same\s+key[\s\S]*key:\s*host/i.test(text);
}

function commandLooksLikeCaffeinate(commandLine, parentPid) {
  const body = String(commandLine || '');
  const pid = String(parentPid || '');
  if (!body || !/(?:^|[\/\s])caffeinate(?:\s|$)/.test(body)) return false;
  return !pid || new RegExp(`(?:^|\\s)-w\\s+${pid}(?:\\s|$)`).test(body);
}

function devTunnelHostArgs(tunnelId, options = {}) {
  const args = ['host', tunnelId];
  if (normalizeHostHeaderMode(options.hostHeaderMode || options.host_header_mode) === HOST_HEADER_MODE_DEFAULT) {
    return args;
  }
  return [...args, '--host-header', 'unchanged', '--origin-header', 'unchanged'];
}

function devTunnelAccessListArgs(tunnelId, options = {}) {
  return ['access', 'list', tunnelId, '-p', String(options.port || 3456), '-j'];
}

function devTunnelUpdateArgs(tunnelId, options = {}) {
  return ['update', tunnelId, '--expiration', String(options.tunnelExpiration || options.tunnel_expiration || DEVTUNNEL_MAX_EXPIRATION)];
}

function devTunnelPrivateAccessResetArgs(tunnelId, options = {}) {
  return ['access', 'reset', tunnelId, '-p', String(options.port || 3456), '-j'];
}

function devTunnelAccessDeleteArgs(tunnelId, index, options = {}) {
  return ['access', 'delete', tunnelId, '-p', String(options.port || 3456), '-i', String(index), '-j'];
}

function devTunnelAnonymousConnectAccessArgs(tunnelId, options = {}) {
  const expiration = String(options.anonymousAccessExpiration || options.anonymous_access_expiration || DEVTUNNEL_MAX_EXPIRATION);
  return [
    'access',
    'create',
    tunnelId,
    '-p', String(options.port || 3456),
    '--anonymous',
    '--scopes', 'connect',
    '-e', expiration,
    '-j',
  ];
}

function caffeinateArgs(options = {}) {
  const parentPid = Number(options.parentPid || process.pid);
  const args = ['-i', '-m'];
  if ((options.platform || process.platform) === 'darwin') args.push('-s');
  if (Number.isFinite(parentPid) && parentPid > 0) args.push('-w', String(parentPid));
  return args;
}

function isoAfter(timestamp, ms) {
  const base = Date.parse(timestamp || '');
  const at = Number.isFinite(base) ? base : Date.now();
  return new Date(at + ms).toISOString();
}

function ageMs(timestamp) {
  const at = Date.parse(timestamp || '');
  if (!Number.isFinite(at)) return Infinity;
  return Date.now() - at;
}

function renewalDueFrom(timestamp, options = {}) {
  const intervalMs = Number(options.renewalIntervalMs || options.renewal_interval_ms || DEVTUNNEL_RENEWAL_INTERVAL_MS);
  if (!Number.isFinite(intervalMs) || intervalMs <= 0) return false;
  return ageMs(timestamp) >= intervalMs;
}

function microsoftTunnelTunnelRenewalDue(state = {}, options = {}) {
  if (!state || typeof state !== 'object') return true;
  return renewalDueFrom(state.last_tunnel_renewed_at || state.tunnel_renewed_at || state.started_at, options);
}

function microsoftTunnelAccessRenewalDue(state = {}, options = {}) {
  const mode = normalizeMicrosoftTunnelAccessMode(state.access_mode || state.access?.mode || options.accessMode || options.access_mode);
  if (mode !== 'ctm_authenticated') return false;
  return renewalDueFrom(state.last_access_renewed_at || state.access?.renewed_at || state.access?.created_at, options);
}

function microsoftTunnelRenewalDue(state = {}, options = {}) {
  return {
    tunnel: microsoftTunnelTunnelRenewalDue(state, options),
    access: microsoftTunnelAccessRenewalDue(state, options),
  };
}

async function inspectManagedTunnelProcess(state = {}, options = {}) {
  const pid = Number(state && state.pid);
  const pidRunning = pidIsRunning(pid);
  const base = {
    pid: Number.isFinite(pid) && pid > 0 ? pid : null,
    pid_running: pidRunning,
    running: false,
    process_verified: false,
    stale_pid: false,
  };
  if (!pidRunning) return base;

  const execFile = options.execFile || defaultExecFile;
  try {
    const result = await execFile('ps', ['-p', String(pid), '-o', 'command='], {
      encoding: 'utf8',
      timeout: options.processInspectTimeoutMs || 1500,
      maxBuffer: 64 * 1024,
    });
    const commandLine = String(result?.stdout || '').trim();
    const matches = commandLooksLikeDevTunnelHost(commandLine, state.tunnel_id);
    const headerPassthrough = matches && commandHasHeaderPassthrough(commandLine);
    return {
      ...base,
      running: matches,
      process_verified: matches,
      stale_pid: !matches,
      header_passthrough: headerPassthrough,
      needs_restart_for_header_passthrough: matches && !headerPassthrough,
      process_command: commandLine.slice(0, 500),
    };
  } catch (err) {
    return {
      ...base,
      stale_pid: true,
      process_error: String(err?.message || err || 'Could not inspect devtunnel host process').slice(0, 500),
    };
  }
}

async function inspectKeepAwakeProcess(state = {}, options = {}) {
  const pid = Number(state && state.pid);
  const parentPid = Number(state && state.parent_pid || options.parentPid || process.pid);
  const pidRunning = pidIsRunning(pid);
  const base = {
    enabled: !!(state && state.enabled),
    configured: !!state,
    pid: Number.isFinite(pid) && pid > 0 ? pid : null,
    parent_pid: Number.isFinite(parentPid) && parentPid > 0 ? parentPid : null,
    pid_running: pidRunning,
    running: false,
    process_verified: false,
    stale_pid: false,
  };
  if (!pidRunning) return base;

  const execFile = options.execFile || defaultExecFile;
  try {
    const result = await execFile('ps', ['-p', String(pid), '-o', 'command='], {
      encoding: 'utf8',
      timeout: options.processInspectTimeoutMs || 1500,
      maxBuffer: 64 * 1024,
    });
    const commandLine = String(result?.stdout || '').trim();
    const matches = commandLooksLikeCaffeinate(commandLine, parentPid);
    return {
      ...base,
      running: matches,
      process_verified: matches,
      stale_pid: !matches,
      process_command: commandLine.slice(0, 500),
    };
  } catch (err) {
    return {
      ...base,
      stale_pid: true,
      process_error: String(err?.message || err || 'Could not inspect caffeinate process').slice(0, 500),
    };
  }
}

function killProcessTree(pid, options = {}) {
  const n = Number(pid);
  if (!Number.isFinite(n) || n <= 0) return false;
  const kill = options.kill || process.kill;
  try {
    kill(-n, 'SIGTERM');
    return true;
  } catch {
    try {
      kill(n, 'SIGTERM');
      return true;
    } catch {
      return false;
    }
  }
}

async function getMicrosoftDevTunnelKeepAwakeStatus(options = {}) {
  const state = loadKeepAwakeState(options);
  if (!state) {
    return {
      configured: false,
      enabled: false,
      running: false,
      supported: (options.platform || process.platform) === 'darwin',
      state_path: keepAwakeStatePath(options),
    };
  }
  const inspected = await inspectKeepAwakeProcess(state, options);
  return {
    ...state,
    ...inspected,
    supported: (options.platform || process.platform) === 'darwin',
    command: state.command || command('caffeinate', caffeinateArgs({ ...options, parentPid: state.parent_pid })).display,
    started_at: state.started_at || '',
    stopped_at: state.stopped_at || '',
    error: state.error || '',
    state_path: keepAwakeStatePath(options),
  };
}

async function enableMicrosoftDevTunnelKeepAwake(options = {}) {
  const platform = options.platform || process.platform;
  const previous = loadKeepAwakeState(options);
  if (platform !== 'darwin') {
    const nextState = {
      ...(previous || {}),
      enabled: false,
      running: false,
      pid: null,
      error: 'Keep-awake mode is only supported on macOS.',
      updated_at: new Date().toISOString(),
    };
    writeKeepAwakeState(nextState, options);
    return {
      ok: false,
      error_code: 'keep_awake_unsupported',
      error: nextState.error,
      keep_awake: await getMicrosoftDevTunnelKeepAwakeStatus(options),
    };
  }

  if (previous && previous.enabled) {
    const inspected = await inspectKeepAwakeProcess(previous, options);
    if (inspected.running) {
      return { ok: true, reused: true, keep_awake: await getMicrosoftDevTunnelKeepAwakeStatus(options) };
    }
  }

  const args = caffeinateArgs(options);
  const spawn = options.spawn || defaultSpawn;
  let child = null;
  try {
    child = spawn('caffeinate', args, {
      detached: true,
      stdio: 'ignore',
    });
  } catch (err) {
    const nextState = {
      ...(previous || {}),
      enabled: true,
      running: false,
      pid: null,
      parent_pid: Number(options.parentPid || process.pid) || null,
      command: command('caffeinate', args).display,
      error: String(err?.message || err || 'Could not start caffeinate').slice(0, 800),
      updated_at: new Date().toISOString(),
    };
    writeKeepAwakeState(nextState, options);
    return { ok: false, error_code: 'keep_awake_start_failed', error: nextState.error, keep_awake: await getMicrosoftDevTunnelKeepAwakeStatus(options) };
  }

  const state = {
    enabled: true,
    running: !!(child && child.pid),
    pid: child && child.pid ? child.pid : null,
    parent_pid: Number(options.parentPid || process.pid) || null,
    command: command('caffeinate', args).display,
    started_at: new Date().toISOString(),
    stopped_at: '',
    error: '',
  };
  writeKeepAwakeState(state, options);
  return { ok: true, reused: false, keep_awake: await getMicrosoftDevTunnelKeepAwakeStatus(options) };
}

async function disableMicrosoftDevTunnelKeepAwake(options = {}) {
  const state = loadKeepAwakeState(options);
  if (!state) {
    return { ok: true, stopped: false, keep_awake: await getMicrosoftDevTunnelKeepAwakeStatus(options) };
  }
  const inspected = await inspectKeepAwakeProcess(state, options);
  const stopped = inspected.running ? killProcessTree(state.pid, options) : false;
  const nextState = {
    ...state,
    enabled: false,
    running: false,
    pid: null,
    stopped_at: new Date().toISOString(),
    stale_pid: inspected.stale_pid || undefined,
    error: '',
  };
  writeKeepAwakeState(nextState, options);
  return { ok: true, stopped, keep_awake: await getMicrosoftDevTunnelKeepAwakeStatus(options) };
}

async function setMicrosoftDevTunnelKeepAwake(enabled, options = {}) {
  return enabled ? enableMicrosoftDevTunnelKeepAwake(options) : disableMicrosoftDevTunnelKeepAwake(options);
}

async function reconcileMicrosoftDevTunnelKeepAwake(options = {}) {
  const keepState = loadKeepAwakeState(options);
  const tunnelState = loadManagedTunnelState(options);
  if (!keepState || !keepState.enabled) {
    return getMicrosoftDevTunnelKeepAwakeStatus(options);
  }
  if (!managedTunnelDesiredRunning(tunnelState)) {
    const disabled = await disableMicrosoftDevTunnelKeepAwake(options);
    return disabled.keep_awake;
  }
  const status = await getMicrosoftDevTunnelKeepAwakeStatus(options);
  if (status.enabled && !status.running && status.supported) {
    const enabled = await enableMicrosoftDevTunnelKeepAwake(options);
    return enabled.keep_awake;
  }
  return status;
}

async function annotateWatchdogState(partial, options = {}) {
  const state = loadManagedTunnelState(options);
  if (!state) return null;
  const nextState = { ...state, ...partial };
  writeManagedTunnelState(nextState, options);
  return nextState;
}

function managedTunnelAccessSummary(partial = {}, options = {}) {
  const port = Number(options.port || 3456);
  const mode = normalizeMicrosoftTunnelAccessMode(partial.mode || options.accessMode || options.access_mode);
  const anonymousConnect = Object.prototype.hasOwnProperty.call(partial, 'anonymous_connect')
    ? !!partial.anonymous_connect
    : mode === 'ctm_authenticated';
  const staleAnonymous = !!partial.stale_anonymous_access
    || !!partial.has_stale_anonymous_access
    || (mode === 'private_microsoft' && anonymousConnect && !partial.reset);
  const error = partial.error || '';
  return {
    mode,
    status: error ? 'error' : (staleAnonymous ? 'stale_anonymous' : mode),
    anonymous_connect: anonymousConnect,
    stale_anonymous_access: staleAnonymous,
    needs_private_reset: staleAnonymous,
    port,
    checked_at: partial.checked_at || new Date().toISOString(),
    already_configured: !!partial.already_configured,
    created: !!partial.created,
    renewed: !!partial.renewed,
    renewed_at: partial.renewed_at || '',
    expiration: partial.expiration || '',
    next_renewal_at: partial.next_renewal_at || '',
    renewal_due: !!partial.renewal_due,
    reset: !!partial.reset,
    anonymous_removed: !!partial.anonymous_removed,
    list_error: partial.list_error || '',
    error,
  };
}

function normalizeMicrosoftTunnelAccessMode(value) {
  const raw = String(value || '').trim().toLowerCase().replace(/[-\s]+/g, '_');
  if (raw === 'private' || raw === 'microsoft' || raw === 'private_microsoft') return 'private_microsoft';
  if (raw === 'anonymous' || raw === 'public' || raw === 'ctm_auth' || raw === 'ctm_authenticated') return 'ctm_authenticated';
  // Default is app-gated (ctm_authenticated): reachable URL + CTM passkey/device
  // auth. It is the only PWA/WebSocket-compatible mode; private is an opt-in.
  return 'ctm_authenticated';
}

// SECURITY / REACHABILITY: the Dev Tunnel default is "ctm_authenticated" — the
// tunnel transport is reachable by URL, and CTM's own app-layer auth (per-origin
// passkey + revocable device token + step-up, behind an unguessable random tunnel
// URL) is the gate. This is the ONLY mode compatible with the phone client, which
// is a PWA that talks to CTM via fetch() + a WebSocket: Dev Tunnels "private" mode
// enforces auth by redirecting the *initial request* to an interactive
// Microsoft/GitHub login page, and programmatic XHR/fetch/WebSocket cannot follow
// that cross-origin redirect — so private silently bricks remote access.
//
// "private_microsoft" therefore is an explicit, deliberate opt-in only. It is
// honored when it comes from a fresh user selection (input.access_mode), the env
// (CTM_MS_TUNNEL_ACCESS_MODE), or options.allowPrivateAccess — but NOT when a
// private value arrives only from restored/persisted state. A persisted private
// value is treated as stale (it predates this policy) and migrated back to the
// app-gated default, so the phone keeps working across headless restarts.
function microsoftTunnelPrivateAccessForced(options = {}) {
  if (options.allowPrivateAccess === true) return true;
  const envMode = String(process.env.CTM_MS_TUNNEL_ACCESS_MODE || '').trim();
  return envMode !== '' && normalizeMicrosoftTunnelAccessMode(envMode) === 'private_microsoft';
}

function resolveMicrosoftTunnelAccessMode(input = {}, options = {}) {
  const fromInput = normalizeMicrosoftTunnelAccessMode(input.access_mode || input.accessMode);
  const inputIsExplicit = !!(input.access_mode || input.accessMode);
  const requested = inputIsExplicit ? fromInput : normalizeMicrosoftTunnelAccessMode(
    options.accessMode
    || options.access_mode
    || process.env.CTM_MS_TUNNEL_ACCESS_MODE
  );
  if (requested === 'private_microsoft') {
    const deliberate = (inputIsExplicit && fromInput === 'private_microsoft')
      || microsoftTunnelPrivateAccessForced(options);
    if (!deliberate) return 'ctm_authenticated';
  }
  return requested;
}

function persistManagedTunnelAccess(tunnelId, access, options = {}) {
  const state = loadManagedTunnelState(options);
  if (!state || normalizeTunnelId(state.tunnel_id || '') !== normalizeTunnelId(tunnelId || '')) return;
  const renewedAt = access.renewed_at || (access.created ? access.checked_at : '') || '';
  writeManagedTunnelState({
    ...state,
    access_mode: access.mode || 'private_microsoft',
    access,
    last_access_check_at: access.checked_at || new Date().toISOString(),
    last_access_renewed_at: renewedAt || state.last_access_renewed_at || '',
    next_access_renewal_at: access.next_renewal_at || (renewedAt ? isoAfter(renewedAt, DEVTUNNEL_RENEWAL_INTERVAL_MS) : state.next_access_renewal_at || ''),
    access_expiration: access.expiration || state.access_expiration || '',
    access_error: access.error || '',
  }, options);
}

function persistManagedTunnelRenewal(tunnelId, renewal, options = {}) {
  const state = loadManagedTunnelState(options);
  if (!state || normalizeTunnelId(state.tunnel_id || '') !== normalizeTunnelId(tunnelId || '')) return;
  writeManagedTunnelState({
    ...state,
    last_tunnel_renewed_at: renewal.renewed_at || state.last_tunnel_renewed_at || '',
    next_tunnel_renewal_at: renewal.next_renewal_at || state.next_tunnel_renewal_at || '',
    tunnel_expiration: renewal.expiration || state.tunnel_expiration || DEVTUNNEL_MAX_EXPIRATION,
    tunnel_renewal_error: renewal.error || '',
  }, options);
}

function parseDevTunnelAccessEntries(stdout) {
  const text = String(stdout || '').trim();
  if (!text) return [];
  let parsed = null;
  try { parsed = JSON.parse(text); } catch {
    return [];
  }
  if (Array.isArray(parsed)) return parsed;
  if (Array.isArray(parsed.accessControlEntries)) return parsed.accessControlEntries;
  if (Array.isArray(parsed.entries)) return parsed.entries;
  if (Array.isArray(parsed.items)) return parsed.items;
  return [];
}

function accessEntryIsDeny(entry) {
  if (!entry || typeof entry !== 'object') return false;
  if (entry.deny === true || entry.isDeny === true || entry.isDenyRule === true) return true;
  const type = String(entry.type || entry.accessType || entry.action || entry.effect || '').toLowerCase();
  if (type === 'deny' || type === 'denied') return true;
  const text = JSON.stringify(entry).toLowerCase();
  return /"deny"\s*:\s*true/.test(text) || /"isdeny"\s*:\s*true/.test(text) || /"effect"\s*:\s*"deny"/.test(text);
}

function accessEntryAllowsAnonymousConnect(entry) {
  if (!entry || typeof entry !== 'object' || accessEntryIsDeny(entry)) return false;
  const text = JSON.stringify(entry).toLowerCase();
  if (!text.includes('anonymous')) return false;
  const rawScopes = entry.scopes || entry.scope || entry.accessScopes || entry.allowedScopes;
  if (Array.isArray(rawScopes)) return rawScopes.map((scope) => String(scope || '').toLowerCase()).includes('connect');
  if (typeof rawScopes === 'string') return rawScopes.toLowerCase().split(/[\s,]+/).includes('connect');
  return text.includes('connect') || !text.includes('scope');
}

function hasAnonymousConnectAccess(stdout) {
  return parseDevTunnelAccessEntries(stdout).some(accessEntryAllowsAnonymousConnect);
}

function anonymousConnectAccessIndices(stdout) {
  return parseDevTunnelAccessEntries(stdout)
    .map((entry, index) => (accessEntryAllowsAnonymousConnect(entry) ? index : -1))
    .filter((index) => index >= 0);
}

async function inspectMicrosoftTunnelAccess(tunnelId, options = {}) {
  const id = normalizeTunnelId(tunnelId);
  const checkedAt = new Date().toISOString();
  if (!id) {
    return managedTunnelAccessSummary({
      checked_at: checkedAt,
      error: 'Microsoft tunnel id is missing.',
    }, options);
  }

  try {
    const list = await execDevTunnel(devTunnelAccessListArgs(id, options), options);
    const body = list?.stdout || list?.stderr || '';
    const hasAnonymous = hasAnonymousConnectAccess(body);
    const mode = resolveMicrosoftTunnelAccessMode({}, options);
    const access = managedTunnelAccessSummary({
      mode,
      anonymous_connect: hasAnonymous,
      already_configured: mode === 'ctm_authenticated' ? hasAnonymous : !hasAnonymous,
      checked_at: checkedAt,
    }, options);
    persistManagedTunnelAccess(id, access, options);
    return access;
  } catch (err) {
    const message = String(err?.stderr || err?.message || err || 'Could not list Microsoft tunnel access.').slice(0, 800);
    const access = managedTunnelAccessSummary({
      checked_at: checkedAt,
      list_error: message,
      error: message,
    }, options);
    persistManagedTunnelAccess(id, access, options);
    return access;
  }
}

function normalizeTunnelId(value) {
  const id = String(value || '').trim().toLowerCase();
  return /^[a-z0-9][a-z0-9-]{2,59}$/.test(id) ? id : '';
}

function createTunnelId() {
  return `ctm-${crypto.randomBytes(6).toString('hex')}`;
}

function parseDevTunnelUserShow(stdout, stderr) {
  const text = String(`${stdout || ''}\n${stderr || ''}`).trim();
  if (!text) return { signed_in: false, account: null };
  if (/not\s+(logged|signed)\s+in|no\s+user|login\s+required/i.test(text)) {
    return { signed_in: false, account: null, raw: text.slice(0, 800) };
  }
  if (/(?:github|microsoft|entra|oauth|auth(?:entication)?|token|credential)[^\n]*(?:refresh|expired|invalid|failed|unauthori[sz]ed)|(?:refresh|expired|invalid|failed|unauthori[sz]ed)[^\n]*(?:github|microsoft|entra|oauth|auth(?:entication)?|token|credential)|invalid_grant|interaction_required|AADSTS/i.test(text)) {
    return {
      signed_in: false,
      account: null,
      raw: text.slice(0, 800),
      error: text.slice(0, 800),
    };
  }
  let parsed = null;
  try { parsed = JSON.parse(text); } catch {}
  if (parsed && typeof parsed === 'object') {
    const display = parsed.displayName || parsed.userName || parsed.username || parsed.email || parsed.name || parsed.id || '';
    return { signed_in: !!display || parsed.isLoggedIn === true || parsed.loggedIn === true, account: { display, raw: parsed } };
  }
  const emailMatch = text.match(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/i);
  const signedIn = !/not\s+(logged|signed)\s+in/i.test(text);
  return {
    signed_in: signedIn,
    account: signedIn ? { display: emailMatch ? emailMatch[0] : text.split(/\r?\n/)[0].slice(0, 120), raw: text.slice(0, 800) } : null,
  };
}

function parseDevTunnelUrls(text, port) {
  const urls = String(text || '').match(DEVTUNNEL_URL_RE) || [];
  let publicUrl = '';
  let inspectUrl = '';
  for (const raw of urls) {
    const normalized = raw.replace(/\/+$/, '');
    if (/-inspect\./i.test(normalized)) {
      if (!inspectUrl) inspectUrl = normalized + '/';
      continue;
    }
    if (!publicUrl) publicUrl = normalized + '/';
    if (String(port || '') && normalized.includes(`-${port}.`)) publicUrl = normalized + '/';
  }
  return {
    origin: publicUrl ? new URL(publicUrl).origin : '',
    mobile_url: publicUrl ? new URL('/m/', publicUrl).toString() : '',
    inspect_url: inspectUrl,
  };
}

function parseDevTunnelLoginHints(text) {
  const body = String(text || '');
  const urls = body.match(HTTP_URL_RE) || [];
  const loginUrl = urls.find((url) => /microsoft|github|aka\.ms|devtunnels/i.test(url)) || urls[0] || '';
  const codeMatch = body.match(/(?:code|enter)\s+(?:the\s+code\s*[:：]?\s*)?([A-Z0-9]{4,}(?:[- ][A-Z0-9]{3,})*)/i)
    || body.match(/\b([A-Z0-9]{4,}-[A-Z0-9-]{4,})\b/);
  return {
    login_url: loginUrl.replace(/[.,;:]+$/, ''),
    device_code: codeMatch ? codeMatch[1].trim() : '',
  };
}

function devTunnelLoginError(text) {
  const body = String(text || '');
  if (/verification\s+code\s+expired/i.test(body)) {
    return {
      error_code: 'device_code_expired',
      error: 'Dev Tunnels sign-in code expired. Start sign-in again and use the newest code shown by CTM.',
    };
  }
  if (/invalid_request/i.test(body) && /response_type/i.test(body)) {
    return {
      error_code: 'microsoft_auth_invalid_request',
      error: 'Microsoft rejected this sign-in page. Start sign-in again from CTM and use the newest Microsoft code page.',
    };
  }
  return {};
}

function resetProcessLogFiles(paths, options = {}) {
  const fsImpl = options.fs || fs;
  for (const filePath of paths) {
    try {
      fsImpl.mkdirSync(path.dirname(filePath), { recursive: true, mode: 0o700 });
      fsImpl.writeFileSync(filePath, '', { mode: 0o600 });
      try { fsImpl.chmodSync(filePath, 0o600); } catch {}
    } catch {}
  }
}

function readLogTail(filePath, options = {}) {
  if (!filePath) return '';
  const fsImpl = options.fs || fs;
  try {
    const body = fsImpl.readFileSync(filePath, 'utf8');
    return body.length > LOG_TAIL_BYTES ? body.slice(-LOG_TAIL_BYTES) : body;
  } catch {
    return '';
  }
}

function processProgressFromState(state, options = {}) {
  if (!state) return { running: false, configured: false, tail: '' };
  const running = !!state.running && pidIsRunning(state.pid);
  const outTail = readLogTail(state.log_path, options);
  const errTail = readLogTail(state.error_log_path, options);
  return {
    ...state,
    configured: true,
    running,
    tail: [outTail, errTail].filter(Boolean).join('\n').slice(-LOG_TAIL_BYTES),
  };
}

function getMicrosoftDevTunnelProgress(options = {}) {
  return {
    install: processProgressFromState(loadInstallProcessState(options), options),
    login: processProgressFromState(loadLoginProcessState(options), options),
  };
}

function openLoginUrl(url, state, options = {}) {
  if (!url || options.openLoginUrl === false || state.opened_url === url) return state;
  const platform = options.platform || process.platform;
  let file = '';
  let args = [];
  if (platform === 'darwin') {
    file = 'open';
    args = [url];
  } else if (platform === 'linux') {
    file = 'xdg-open';
    args = [url];
  } else {
    return state;
  }
  try {
    const spawn = options.spawn || defaultSpawn;
    spawn(file, args, { detached: true, stdio: 'ignore' });
    return { ...state, opened_url: url, opened_at: new Date().toISOString() };
  } catch (err) {
    return { ...state, open_error: String(err?.message || err || 'Could not open sign-in URL').slice(0, 500) };
  }
}

async function detectLoginStatus(options = {}) {
  const execFile = options.execFile || defaultExecFile;
  try {
    const result = await execFile('devtunnel', ['user', 'show'], {
      encoding: 'utf8',
      timeout: options.timeoutMs || 3000,
      maxBuffer: 512 * 1024,
    });
    return parseDevTunnelUserShow(result?.stdout, result?.stderr);
  } catch (err) {
    if (err && err.code === 'ENOENT') {
      return { installed: false, signed_in: false, account: null, error: 'devtunnel CLI is not installed or not on PATH.' };
    }
    const parsed = parseDevTunnelUserShow(err?.stdout, err?.stderr || err?.message);
    return { installed: true, ...parsed };
  }
}

async function checkMicrosoftDevTunnelLoginStatus(options = {}) {
  const previous = loadLoginProcessState(options) || {};
  const checkedAt = new Date().toISOString();
  const login = await detectLoginStatus(options);
  const provider = previous.provider || normalizeLoginProvider(options);
  const signedIn = !!login.signed_in;
  const account = login.account || null;
  const nextState = {
    ...previous,
    provider,
    provider_label: previous.provider_label || loginProviderLabel(provider),
    installed: login.installed !== false,
    signed_in: signedIn,
    account,
    account_display: account && account.display ? String(account.display) : '',
    login_checked_at: checkedAt,
    login_check_error: signedIn ? '' : String(login.error || '').slice(0, 800),
  };
  if (signedIn) {
    nextState.running = false;
    nextState.finished_at = nextState.finished_at || checkedAt;
    nextState.error = '';
    nextState.error_code = '';
    nextState.verified_at = checkedAt;
  } else if (login.installed === false) {
    nextState.running = false;
    nextState.error_code = 'devtunnel_cli_missing';
    nextState.error = login.error || 'devtunnel CLI is not installed or not on PATH.';
  }
  if (previous.signed_in === true && !signedIn && login.installed !== false) {
    appendManagedTunnelHostEvent({
      type: 'credential_expired',
      detail: nextState.login_check_error || `${loginProviderLabel(provider)} sign-in is no longer valid.`,
    }, options);
  } else if (previous.signed_in === false && signedIn) {
    appendManagedTunnelHostEvent({ type: 'signed_in', detail: nextState.account_display || '' }, options);
  }
  writeLoginProcessState(nextState, options);
  const progress = getMicrosoftDevTunnelProgress(options);
  const setup = options.includeSetup === false
    ? null
    : await detectMicrosoftDevTunnelSetup(options).catch(() => null);
  return {
    ok: signedIn,
    signed_in: signedIn,
    account,
    login: progress.login,
    setup,
    microsoft_dev_tunnel: setup,
    progress,
    error: signedIn ? '' : (login.error || 'Dev Tunnels is not signed in yet. Finish the browser sign-in, then check again.'),
  };
}

async function detectManagedMicrosoftDevTunnel(options = {}) {
  const state = loadManagedTunnelState(options);
  if (!state) return { configured: false, running: false };
  const processInfo = await inspectManagedTunnelProcess(state, options);
  const desiredRunning = managedTunnelDesiredRunning(state);
  const acceptsDefaultHeaders = managedTunnelAcceptsDefaultHostHeaders(state);
  return {
    configured: true,
    desired_running: desiredRunning,
    running: !!processInfo.running,
    pid: state.pid || null,
    pid_running: !!processInfo.pid_running,
    process_verified: !!processInfo.process_verified,
    stale_pid: !!processInfo.stale_pid,
    header_passthrough: !!processInfo.header_passthrough,
    host_header_mode: state.host_header_mode || (processInfo.header_passthrough ? HOST_HEADER_MODE_PASSTHROUGH : ''),
    header_passthrough_required: !acceptsDefaultHeaders,
    needs_restart_for_header_passthrough: !!processInfo.needs_restart_for_header_passthrough && !acceptsDefaultHeaders,
    process_error: processInfo.process_error || '',
    tunnel_id: state.tunnel_id || '',
    origin: state.origin || '',
    mobile_url: state.mobile_url || '',
    inspect_url: state.inspect_url || '',
    log_path: state.log_path || '',
    error_log_path: state.error_log_path || '',
    run_command: state.run_command || '',
    started_at: state.started_at || '',
    stopped_at: state.stopped_at || '',
    last_restore_failed_at: state.last_restore_failed_at || '',
    restore_error: state.restore_error || '',
    last_watchdog_check_at: state.last_watchdog_check_at || '',
    last_watchdog_recovered_at: state.last_watchdog_recovered_at || '',
    watchdog_error: state.watchdog_error || '',
    header_passthrough_fallback: !!state.header_passthrough_fallback,
    header_passthrough_fallback_reason: state.header_passthrough_fallback_reason || '',
    access_mode: state.access_mode || (state.access && state.access.mode) || '',
    access: state.access || null,
    last_access_check_at: state.last_access_check_at || (state.access && state.access.checked_at) || '',
    last_access_renewed_at: state.last_access_renewed_at || (state.access && state.access.renewed_at) || '',
    next_access_renewal_at: state.next_access_renewal_at || (state.access && state.access.next_renewal_at) || '',
    access_expiration: state.access_expiration || (state.access && state.access.expiration) || '',
    access_error: state.access_error || (state.access && state.access.error) || '',
    last_tunnel_renewed_at: state.last_tunnel_renewed_at || '',
    next_tunnel_renewal_at: state.next_tunnel_renewal_at || '',
    tunnel_expiration: state.tunnel_expiration || '',
    tunnel_renewal_error: state.tunnel_renewal_error || '',
    host_events: Array.isArray(state.host_events) ? state.host_events : [],
    state_path: managedStatePath(options),
  };
}

function getTrafficInspection() {
  return {
    entries: trafficEntries.slice().reverse(),
    entries_total: trafficEntries.length,
    last_request_at: trafficEntries.length ? trafficEntries[trafficEntries.length - 1].at : '',
  };
}

function microsoftDevTunnelProbeUrl(input = {}) {
  const managed = input.managed_tunnel && typeof input.managed_tunnel === 'object' ? input.managed_tunnel : {};
  const raw = managed.mobile_url || input.mobile_url || managed.origin || input.origin || '';
  if (!raw) return '';
  try {
    const url = new URL(raw);
    const hostname = url.hostname.toLowerCase();
    if (!hostname.endsWith('.devtunnels.ms')) return '';
    url.pathname = '/m/';
    url.search = '';
    url.hash = '';
    return url.toString();
  } catch {
    return '';
  }
}

function microsoftDevTunnelProbeDiagnosis(status, wwwAuthenticate, location) {
  const auth = String(wwwAuthenticate || '');
  const redirect = String(location || '');
  if (status === 401 && /(?:^|[\s,])tunnel(?:[\s,]|$)/i.test(auth)) {
    return {
      diagnosis: 'tunnel_auth_required',
      blocked_by_tunnel_auth: true,
      ctm_reachable: false,
      message: 'Microsoft Dev Tunnels is reachable and the private access gate is asking the browser to sign in before CTM receives the request.',
    };
  }
  if (status >= 300 && status < 400 && /(?:tunnels\.api\.visualstudio\.com\/auth|\/auth\/(?:github|microsoft|entra))/i.test(redirect)) {
    return {
      diagnosis: 'tunnel_auth_required',
      blocked_by_tunnel_auth: true,
      ctm_reachable: false,
      message: 'Microsoft Dev Tunnels redirected the browser to tunnel authorization before CTM received the request.',
    };
  }
  if (status >= 200 && status < 300) {
    return {
      diagnosis: 'ctm_reachable',
      blocked_by_tunnel_auth: false,
      ctm_reachable: true,
      message: 'The tunnel URL reached CTM from this Mac.',
    };
  }
  return {
    diagnosis: status ? 'unexpected_http_status' : 'no_http_status',
    blocked_by_tunnel_auth: false,
    ctm_reachable: false,
    message: status
      ? `The tunnel URL responded with HTTP ${status}; CTM did not confirm a normal mobile page response.`
      : 'The tunnel URL did not return an HTTP status.',
  };
}

async function probeMicrosoftDevTunnelPublicAccess(input = {}, options = {}) {
  const url = microsoftDevTunnelProbeUrl(input);
  const checkedAt = new Date().toISOString();
  if (!url) {
    return {
      ok: false,
      checked: false,
      checked_at: checkedAt,
      diagnosis: 'not_configured',
      reachable: false,
      ctm_reachable: false,
      blocked_by_tunnel_auth: false,
      message: 'No Microsoft tunnel URL is configured yet.',
    };
  }

  const fetchImpl = options.fetch || globalThis.fetch;
  if (typeof fetchImpl !== 'function') {
    return {
      ok: false,
      checked: false,
      checked_at: checkedAt,
      url,
      diagnosis: 'probe_unsupported',
      reachable: false,
      ctm_reachable: false,
      blocked_by_tunnel_auth: false,
      message: 'This Node runtime cannot run the Microsoft tunnel URL check because fetch is unavailable.',
    };
  }

  const timeoutMs = Number(options.timeoutMs || PUBLIC_PROBE_TIMEOUT_MS);
  const controller = typeof AbortController !== 'undefined' ? new AbortController() : null;
  const timer = controller && Number.isFinite(timeoutMs) && timeoutMs > 0
    ? setTimeout(() => controller.abort(), timeoutMs)
    : null;
  if (timer && typeof timer.unref === 'function') timer.unref();

  try {
    const response = await fetchImpl(url, {
      method: 'GET',
      redirect: 'manual',
      signal: controller ? controller.signal : undefined,
      headers: {
        Accept: 'text/html',
        'Cache-Control': 'no-cache',
        'X-Tunnel-Skip-AntiPhishing-Page': '1',
      },
    });
    try {
      if (response && response.body && typeof response.body.cancel === 'function') {
        const cancelled = response.body.cancel();
        if (cancelled && typeof cancelled.catch === 'function') cancelled.catch(() => {});
      }
    } catch {}
    const status = Number(response && response.status || 0);
    const wwwAuthenticate = response && response.headers && typeof response.headers.get === 'function'
      ? String(response.headers.get('www-authenticate') || '')
      : '';
    const location = response && response.headers && typeof response.headers.get === 'function'
      ? String(response.headers.get('location') || '')
      : '';
    const diagnosis = microsoftDevTunnelProbeDiagnosis(status, wwwAuthenticate, location);
    return {
      ok: true,
      checked: true,
      checked_at: checkedAt,
      url,
      status,
      status_text: String(response && response.statusText || ''),
      reachable: true,
      www_authenticate: wwwAuthenticate.slice(0, 160),
      location: location ? location.split('?')[0].slice(0, 240) : '',
      anti_phishing_skipped: true,
      ...diagnosis,
    };
  } catch (err) {
    const aborted = err && err.name === 'AbortError';
    return {
      ok: false,
      checked: true,
      checked_at: checkedAt,
      url,
      diagnosis: aborted ? 'timeout' : 'network_error',
      reachable: false,
      ctm_reachable: false,
      blocked_by_tunnel_auth: false,
      error: String(err?.message || err || 'Microsoft tunnel URL check failed.').slice(0, 500),
      message: aborted
        ? 'The Microsoft tunnel URL check timed out before CTM could be reached.'
        : 'The Microsoft tunnel URL could not be reached from this Mac.',
    };
  } finally {
    if (timer) clearTimeout(timer);
  }
}

function clearMicrosoftDevTunnelTraffic() {
  trafficEntries.splice(0, trafficEntries.length);
  return getTrafficInspection();
}

function sanitizeRequestPath(reqUrl) {
  try {
    const u = new URL(reqUrl, 'http://ctm.local');
    for (const key of Array.from(u.searchParams.keys())) {
      if (SENSITIVE_QUERY_KEYS.has(key.toLowerCase())) u.searchParams.set(key, '[redacted]');
    }
    return u.pathname + u.search;
  } catch {
    return String(reqUrl || '').replace(/([?&](?:claim|secret|token|ctm_token|code|state)=)[^&\s]+/gi, '$1[redacted]').slice(0, 500);
  }
}

function recordMicrosoftDevTunnelTraffic(req, res, options = {}) {
  let host = String(req.headers.host || '').toLowerCase();
  const origin = requestOrigin(req);
  if (origin) {
    host = new URL(origin).host.toLowerCase() || host;
  }
  if (!host.includes('.devtunnels.ms')) return;

  const started = Date.now();
  res.once('finish', () => {
    const entry = {
      at: new Date().toISOString(),
      method: req.method || '',
      path: sanitizeRequestPath(req.url || ''),
      status: res.statusCode || 0,
      duration_ms: Math.max(0, Date.now() - started),
      host: host.slice(0, 160),
      user_agent: String(req.headers['user-agent'] || '').slice(0, 220),
      remote_address: String(req.socket?.remoteAddress || '').slice(0, 100),
    };
    trafficEntries.push(entry);
    if (trafficEntries.length > MAX_TRAFFIC_ENTRIES) {
      trafficEntries.splice(0, trafficEntries.length - MAX_TRAFFIC_ENTRIES);
    }
  });
}

async function detectMicrosoftDevTunnelSetup(options = {}) {
  const execFile = options.execFile || defaultExecFile;
  let version = '';
  try {
    const versionResult = await execFile('devtunnel', ['--version'], {
      encoding: 'utf8',
      timeout: options.timeoutMs || 2500,
      maxBuffer: 256 * 1024,
    });
    version = String(versionResult?.stdout || versionResult?.stderr || '').trim().split(/\r?\n/)[0];
  } catch (err) {
    if (err && err.code === 'ENOENT') {
      return {
        installed: false,
        available: false,
        signed_in: false,
        error_code: 'devtunnel_cli_missing',
        error: 'Microsoft devtunnel CLI is not installed or not on PATH.',
        commands: microsoftDevTunnelCommands(options),
        managed_tunnel: await detectManagedMicrosoftDevTunnel(options),
        keep_awake: await getMicrosoftDevTunnelKeepAwakeStatus(options),
        traffic: getTrafficInspection(),
      };
    }
  }

  const login = await detectLoginStatus(options);
  let managed = await detectManagedMicrosoftDevTunnel(options);
  if (login.signed_in && managed.tunnel_id) {
    const access = await inspectMicrosoftTunnelAccess(managed.tunnel_id, {
      ...options,
      accessMode: managed.access_mode || managed.access?.mode || options.accessMode || options.access_mode,
    });
    managed = {
      ...managed,
      access,
      access_mode: access.mode,
      last_access_check_at: access.checked_at,
      access_error: access.error || '',
    };
  }
  return {
    installed: login.installed !== false,
    available: login.installed !== false && !!login.signed_in,
    signed_in: !!login.signed_in,
    account: login.account || null,
    login_provider: loginStateProvider(loadLoginProcessState(options) || {}),
    version,
    origin: managed.origin || '',
    mobile_url: managed.mobile_url || '',
    inspect_url: managed.inspect_url || '',
    tunnel_id: managed.tunnel_id || '',
    port: Number(options.port || 3456),
    protocol: 'http',
    managed_tunnel: managed,
    keep_awake: await getMicrosoftDevTunnelKeepAwakeStatus(options),
    traffic: getTrafficInspection(),
    commands: microsoftDevTunnelCommands(options),
  };
}

async function installMicrosoftDevTunnelCli(options = {}) {
  const before = await detectMicrosoftDevTunnelSetup(options);
  if (before.installed) {
    return {
      ok: true,
      already_installed: true,
      installed: true,
      setup: before,
    };
  }

  const platform = options.platform || process.platform;
  if (platform !== 'darwin') {
    return {
      ok: false,
      error_code: 'devtunnel_install_unsupported',
      error: 'Automatic Microsoft Dev Tunnels install is only supported on macOS with Homebrew.',
      setup: before,
    };
  }

  const execFile = options.execFile || defaultExecFile;
  try {
    await execFile('brew', ['install', '--cask', 'devtunnel'], {
      encoding: 'utf8',
      timeout: options.installTimeoutMs || options.commandTimeoutMs || 300000,
      maxBuffer: 5 * 1024 * 1024,
    });
  } catch (err) {
    return {
      ok: false,
      error_code: err?.code === 'ENOENT' ? 'homebrew_missing' : 'devtunnel_install_failed',
      error: String(err?.stderr || err?.message || err || 'Microsoft Dev Tunnels install failed.').slice(0, 1000),
      setup: before,
    };
  }

  const after = await detectMicrosoftDevTunnelSetup(options);
  return {
    ok: !!after.installed,
    already_installed: false,
    installed: !!after.installed,
    error_code: after.installed ? '' : 'devtunnel_install_not_detected',
    error: after.installed ? '' : 'Homebrew finished, but CTM still cannot find the devtunnel CLI on PATH.',
    setup: after,
  };
}

async function startMicrosoftDevTunnelInstall(options = {}) {
  const before = await detectMicrosoftDevTunnelSetup(options);
  if (before.installed) {
    return {
      ok: true,
      already_installed: true,
      install: { running: false, already_installed: true, command: microsoftDevTunnelCommands(options).install.display },
      progress: getMicrosoftDevTunnelProgress(options),
      setup: before,
    };
  }

  const platform = options.platform || process.platform;
  if (platform !== 'darwin') {
    return {
      ok: false,
      error_code: 'devtunnel_install_unsupported',
      error: 'Automatic Microsoft Dev Tunnels install is only supported on macOS with Homebrew.',
      progress: getMicrosoftDevTunnelProgress(options),
      setup: before,
    };
  }

  const fsImpl = options.fs || fs;
  fsImpl.mkdirSync(setupDir(options), { recursive: true, mode: 0o700 });
  fsImpl.mkdirSync(logsDir(options), { recursive: true, mode: 0o700 });
  const logPath = path.join(logsDir(options), 'devtunnel-install.log');
  const errorLogPath = path.join(logsDir(options), 'devtunnel-install.err');
  resetProcessLogFiles([logPath, errorLogPath], options);
  const args = ['install', '--cask', 'devtunnel'];
  const spawn = options.spawn || defaultSpawn;
  const child = spawn('brew', args, {
    cwd: setupDir(options),
    detached: true,
    env: { ...process.env },
    stdio: ['ignore', 'pipe', 'pipe'],
  });
  const out = fsImpl.createWriteStream ? fsImpl.createWriteStream(logPath, { flags: 'a', mode: 0o600 }) : null;
  const err = fsImpl.createWriteStream ? fsImpl.createWriteStream(errorLogPath, { flags: 'a', mode: 0o600 }) : null;
  let state = {
    pid: child && child.pid ? child.pid : null,
    running: !!(child && child.pid),
    command: command('brew', args).display,
    log_path: logPath,
    error_log_path: errorLogPath,
    started_at: new Date().toISOString(),
  };
  writeInstallProcessState(state, options);
  function update(partial) {
    state = { ...state, ...partial };
    writeInstallProcessState(state, options);
  }
  if (child.stdout) child.stdout.on('data', (chunk) => { if (out && !out.destroyed) out.write(String(chunk || '')); });
  if (child.stderr) child.stderr.on('data', (chunk) => { if (err && !err.destroyed) err.write(String(chunk || '')); });
  child.once('error', (spawnErr) => {
    update({ running: false, error: String(spawnErr?.message || spawnErr || 'Install failed').slice(0, 800), finished_at: new Date().toISOString() });
    try { if (out) out.end(); } catch {}
    try { if (err) err.end(); } catch {}
  });
  child.once('exit', (code, signal) => {
    update({ running: false, exit_code: code, signal: signal || '', finished_at: new Date().toISOString() });
    try { if (out) out.end(); } catch {}
    try { if (err) err.end(); } catch {}
  });

  return {
    ok: true,
    already_installed: false,
    install: { ...state, state_path: installStatePath(options) },
    progress: getMicrosoftDevTunnelProgress(options),
    setup: before,
  };
}

function microsoftDevTunnelCommands(options = {}) {
  const port = Number(options.port || 3456);
  return {
    install: process.platform === 'darwin'
      ? command('brew', ['install', '--cask', 'devtunnel'])
      : command('devtunnel', ['--help']),
    login: command('devtunnel', ['user', 'login', '-g']),
    device_login: command('devtunnel', ['user', 'login', '-g', '-d']),
    microsoft_device_login: command('devtunnel', ['user', 'login', '-e', '-d']),
    logout: command('devtunnel', ['user', 'logout']),
    access_private_reset: command('devtunnel', devTunnelPrivateAccessResetArgs('TUNNELID', { port })),
    access_ctm_authenticated: command('devtunnel', devTunnelAnonymousConnectAccessArgs('TUNNELID', { port })),
    renew_tunnel: command('devtunnel', devTunnelUpdateArgs('TUNNELID', { port })),
    host_temporary: command('devtunnel', [
      'host',
      '-p', String(port),
      '--protocol', 'http',
      '--expiration', DEVTUNNEL_MAX_EXPIRATION,
      '--host-header', 'unchanged',
      '--origin-header', 'unchanged',
    ]),
    host_temporary_fallback: command('devtunnel', [
      'host',
      '-p', String(port),
      '--protocol', 'http',
      '--expiration', DEVTUNNEL_MAX_EXPIRATION,
    ]),
  };
}

async function execDevTunnel(args, options = {}) {
  const execFile = options.execFile || defaultExecFile;
  return execFile('devtunnel', args, {
    encoding: 'utf8',
    timeout: options.commandTimeoutMs || 15000,
    maxBuffer: 2 * 1024 * 1024,
  });
}

function ignoreAlreadyExists(err) {
  const text = String(`${err?.stdout || ''}\n${err?.stderr || ''}\n${err?.message || ''}`);
  return /already\s+exists|conflict/i.test(text);
}

async function ensurePrivateConnectAccess(tunnelId, options = {}) {
  const checkedAt = new Date().toISOString();
  const listArgs = devTunnelAccessListArgs(tunnelId, options);
  let listError = '';
  try {
    const list = await execDevTunnel(listArgs, options);
    const hasAnonymous = hasAnonymousConnectAccess(list?.stdout || list?.stderr || '');
    if (!hasAnonymous) {
      const access = managedTunnelAccessSummary({
        already_configured: true,
        checked_at: checkedAt,
      }, options);
      persistManagedTunnelAccess(tunnelId, access, options);
      return access;
    }
  } catch (err) {
    listError = String(err?.stderr || err?.message || err || 'Could not list Microsoft tunnel access.').slice(0, 500);
    // Older CLI builds and transient service errors can make listing fail. The
    // reset below is still safe: it returns the port to Dev Tunnels defaults.
  }

  try {
    await execDevTunnel(devTunnelPrivateAccessResetArgs(tunnelId, options), options);
    const access = managedTunnelAccessSummary({
      reset: true,
      anonymous_removed: !listError,
      list_error: listError,
      checked_at: checkedAt,
    }, options);
    persistManagedTunnelAccess(tunnelId, access, options);
    return access;
  } catch (err) {
    const message = String(err?.stderr || err?.message || err || 'Could not reset Microsoft tunnel access to private.').slice(0, 800);
    const access = managedTunnelAccessSummary({
      checked_at: checkedAt,
      list_error: listError,
      error: message,
    }, options);
    persistManagedTunnelAccess(tunnelId, access, options);
    throw err;
  }
}

async function renewCtmAuthenticatedConnectAccess(tunnelId, accessListBody, options = {}) {
  const checkedAt = new Date().toISOString();
  const indices = anonymousConnectAccessIndices(accessListBody);
  // Delete descending so the CLI's zero-based indices do not shift underneath us.
  for (const index of indices.slice().sort((a, b) => b - a)) {
    await execDevTunnel(devTunnelAccessDeleteArgs(tunnelId, index, options), options);
  }
  await execDevTunnel(devTunnelAnonymousConnectAccessArgs(tunnelId, options), options);
  const access = managedTunnelAccessSummary({
    mode: 'ctm_authenticated',
    renewed: true,
    renewed_at: checkedAt,
    expiration: String(options.anonymousAccessExpiration || options.anonymous_access_expiration || DEVTUNNEL_MAX_EXPIRATION),
    next_renewal_at: isoAfter(checkedAt, DEVTUNNEL_RENEWAL_INTERVAL_MS),
    checked_at: checkedAt,
  }, options);
  persistManagedTunnelAccess(tunnelId, access, options);
  return access;
}

async function ensureCtmAuthenticatedConnectAccess(tunnelId, options = {}) {
  const checkedAt = new Date().toISOString();
  const listArgs = devTunnelAccessListArgs(tunnelId, options);
  let listError = '';
  let body = '';
  try {
    const list = await execDevTunnel(listArgs, options);
    body = list?.stdout || list?.stderr || '';
  } catch (err) {
    listError = String(err?.stderr || err?.message || err || 'Could not list Microsoft tunnel access.').slice(0, 500);
    // Listing can fail on older CLI builds or transient service errors. Try to
    // establish the narrow connect-only rule; CTM still owns application auth.
  }
  const hasAnonymous = hasAnonymousConnectAccess(body);
  if (hasAnonymous) {
    const state = loadManagedTunnelState(options) || {};
    const renewalDue = options.renewAccess === true || options.renew_access === true || microsoftTunnelAccessRenewalDue(state, options);
    if (renewalDue) {
      return await renewCtmAuthenticatedConnectAccess(tunnelId, body, options);
    }
    const access = managedTunnelAccessSummary({
      mode: 'ctm_authenticated',
      already_configured: true,
      renewal_due: false,
      checked_at: checkedAt,
    }, options);
    persistManagedTunnelAccess(tunnelId, access, options);
    return access;
  }

  try {
    await execDevTunnel(devTunnelAnonymousConnectAccessArgs(tunnelId, options), options);
    const access = managedTunnelAccessSummary({
      mode: 'ctm_authenticated',
      created: true,
      renewed_at: checkedAt,
      expiration: String(options.anonymousAccessExpiration || options.anonymous_access_expiration || DEVTUNNEL_MAX_EXPIRATION),
      next_renewal_at: isoAfter(checkedAt, DEVTUNNEL_RENEWAL_INTERVAL_MS),
      list_error: listError,
      checked_at: checkedAt,
    }, options);
    persistManagedTunnelAccess(tunnelId, access, options);
    return access;
  } catch (err) {
    if (ignoreAlreadyExists(err)) {
      const access = managedTunnelAccessSummary({
        mode: 'ctm_authenticated',
        already_configured: true,
        renewal_due: false,
        list_error: listError,
        checked_at: checkedAt,
      }, options);
      persistManagedTunnelAccess(tunnelId, access, options);
      return access;
    }
    const message = String(err?.stderr || err?.message || err || 'Could not enable CTM-authenticated Microsoft tunnel access.').slice(0, 800);
    const access = managedTunnelAccessSummary({
      mode: 'ctm_authenticated',
      checked_at: checkedAt,
      list_error: listError,
      error: message,
    }, options);
    persistManagedTunnelAccess(tunnelId, access, options);
    throw err;
  }
}

async function ensureMicrosoftTunnelConnectAccess(tunnelId, options = {}) {
  const accessMode = resolveMicrosoftTunnelAccessMode(options.input || {}, options);
  // Default is the app-gated (ctm_authenticated) anonymous-connect ACE so the
  // phone PWA + WebSocket can reach CTM; CTM's own passkey/device-token auth is
  // the gate. Only take the private path when private was a deliberate opt-in
  // (resolveMicrosoftTunnelAccessMode already migrated stale persisted private
  // back to ctm_authenticated).
  if (accessMode === 'private_microsoft') {
    return ensurePrivateConnectAccess(tunnelId, { ...options, accessMode: 'private_microsoft' });
  }
  return ensureCtmAuthenticatedConnectAccess(tunnelId, { ...options, accessMode: 'ctm_authenticated' });
}

async function resetMicrosoftDevTunnelPrivateAccess(input = {}, options = {}) {
  // This is the explicit, deliberate "switch to private" action, so it carries the
  // private opt-in flag — otherwise the follow-up detect/inspect would resolve the
  // mode without it and migrate the just-set private back to the app-gated default.
  const mergedOptions = {
    ...options,
    accessMode: 'private_microsoft',
    allowPrivateAccess: true,
    input: { ...(options.input || {}), ...(input || {}), access_mode: 'private_microsoft' },
  };
  const state = loadManagedTunnelState(mergedOptions) || {};
  const tunnelId = normalizeTunnelId(input.tunnel_id || input.tunnelId || state.tunnel_id || '');
  if (!tunnelId) {
    return {
      ok: false,
      error_code: 'microsoft_tunnel_missing',
      error: 'No managed Microsoft Dev Tunnel exists yet.',
      setup: await detectMicrosoftDevTunnelSetup(mergedOptions).catch(() => null),
    };
  }
  const login = await detectLoginStatus(mergedOptions);
  if (login.installed === false || !login.signed_in) {
    return {
      ok: false,
      error_code: login.installed === false ? 'devtunnel_cli_missing' : 'microsoft_tunnel_sign_in_required',
      error: login.installed === false
        ? 'Microsoft devtunnel CLI is not installed or not on PATH.'
        : 'Sign in to Microsoft Dev Tunnels on this Mac before resetting tunnel access.',
      setup: await detectMicrosoftDevTunnelSetup(mergedOptions).catch(() => null),
    };
  }
  try {
    const access = await ensurePrivateConnectAccess(tunnelId, mergedOptions);
    const managed = await detectManagedMicrosoftDevTunnel(mergedOptions);
    return {
      ok: true,
      tunnel_id: tunnelId,
      access,
      managed_tunnel: { ...managed, access },
      setup: await detectMicrosoftDevTunnelSetup(mergedOptions),
    };
  } catch (err) {
    return {
      ok: false,
      error_code: 'microsoft_tunnel_private_reset_failed',
      error: String(err?.stderr || err?.message || err || 'Could not reset Microsoft tunnel access to private.').slice(0, 800),
      setup: await detectMicrosoftDevTunnelSetup(mergedOptions).catch(() => null),
    };
  }
}

async function renewPersistentTunnelExpiration(tunnelId, options = {}) {
  const checkedAt = new Date().toISOString();
  try {
    await execDevTunnel(devTunnelUpdateArgs(tunnelId, options), options);
    const renewal = {
      ok: true,
      renewed: true,
      renewed_at: checkedAt,
      expiration: String(options.tunnelExpiration || options.tunnel_expiration || DEVTUNNEL_MAX_EXPIRATION),
      next_renewal_at: isoAfter(checkedAt, DEVTUNNEL_RENEWAL_INTERVAL_MS),
      error: '',
    };
    persistManagedTunnelRenewal(tunnelId, renewal, options);
    return renewal;
  } catch (err) {
    const renewal = {
      ok: false,
      renewed: false,
      checked_at: checkedAt,
      expiration: String(options.tunnelExpiration || options.tunnel_expiration || DEVTUNNEL_MAX_EXPIRATION),
      error: String(err?.stderr || err?.message || err || 'Could not renew Microsoft tunnel expiration.').slice(0, 800),
    };
    persistManagedTunnelRenewal(tunnelId, renewal, options);
    return renewal;
  }
}

function createdTunnelRenewal(options = {}) {
  const checkedAt = new Date().toISOString();
  return {
    ok: true,
    created: true,
    renewed: true,
    renewed_at: checkedAt,
    expiration: String(options.tunnelExpiration || options.tunnel_expiration || DEVTUNNEL_MAX_EXPIRATION),
    next_renewal_at: isoAfter(checkedAt, DEVTUNNEL_RENEWAL_INTERVAL_MS),
    error: '',
  };
}

async function ensurePersistentTunnel(tunnelId, options = {}) {
  const previousState = loadManagedTunnelState(options) || {};
  let created = false;
  try {
    await execDevTunnel(['create', tunnelId, '--expiration', String(options.tunnelExpiration || options.tunnel_expiration || DEVTUNNEL_MAX_EXPIRATION)], options);
    created = true;
  } catch (err) {
    if (!ignoreAlreadyExists(err)) throw err;
  }
  const renewalDue = options.renewTunnel === true || options.renew_tunnel === true || microsoftTunnelTunnelRenewalDue(previousState, options);
  const tunnelRenewal = created ? createdTunnelRenewal(options) : (renewalDue ? await renewPersistentTunnelExpiration(tunnelId, options) : {
    ok: true,
    renewed: false,
    expiration: previousState.tunnel_expiration || String(options.tunnelExpiration || options.tunnel_expiration || DEVTUNNEL_MAX_EXPIRATION),
    renewed_at: previousState.last_tunnel_renewed_at || '',
    next_renewal_at: previousState.next_tunnel_renewal_at || '',
    error: previousState.tunnel_renewal_error || '',
  });
  try {
    await execDevTunnel(['port', 'create', tunnelId, '-p', String(options.port || 3456), '--protocol', 'http'], options);
  } catch (err) {
    if (!ignoreAlreadyExists(err)) {
      try {
        await execDevTunnel(['port', 'update', tunnelId, '-p', String(options.port || 3456), '--protocol', 'http'], options);
      } catch (updateErr) {
        if (!ignoreAlreadyExists(updateErr)) throw err;
      }
    }
  }
  // Fault-isolate access configuration from tunnel exposure. A transient
  // `devtunnel access` failure must NOT abort hosting the tunnel — CTM's app-layer
  // auth still gates every request, and a missing ACE at worst costs a one-time
  // sign-in, never a full outage. Surface the error in the access summary instead.
  let access;
  try {
    const accessRenewalDue = options.renewAccess === true || options.renew_access === true || microsoftTunnelAccessRenewalDue(previousState, options);
    access = await ensureMicrosoftTunnelConnectAccess(tunnelId, { ...options, renewAccess: accessRenewalDue });
  } catch (err) {
    access = managedTunnelAccessSummary({
      mode: resolveMicrosoftTunnelAccessMode(options.input || {}, options),
      checked_at: new Date().toISOString(),
      error: String(err?.stderr || err?.message || err || 'tunnel access configuration failed').slice(0, 800),
    }, options);
  }
  return { access, tunnel_renewal: tunnelRenewal };
}

function waitForHostReady(child, logStreams, options = {}) {
  const port = Number(options.port || 3456);
  const timeoutMs = Number(options.hostReadyTimeoutMs || HOST_READY_TIMEOUT_MS);
  return new Promise((resolve, reject) => {
    let combined = '';
    let settled = false;
    function readyError(message) {
      const tail = combined.trim().slice(-1200);
      const err = new Error(tail ? `${message}\n${tail}` : message);
      err.host_log_tail = tail;
      return err;
    }
    const timer = setTimeout(() => {
      if (settled) return;
      settled = true;
      const urls = parseDevTunnelUrls(combined, port);
      if (urls.origin) resolve(urls);
      else reject(readyError('devtunnel host started but did not print a tunnel URL yet. Check the devtunnel log.'));
    }, timeoutMs);
    function onData(chunk, stream) {
      const text = chunk ? String(chunk) : '';
      combined += text;
      if (stream && !stream.destroyed) stream.write(text);
      const urls = parseDevTunnelUrls(combined, port);
      if (urls.origin && !settled) {
        settled = true;
        clearTimeout(timer);
        resolve(urls);
      }
    }
    if (child.stdout) child.stdout.on('data', (chunk) => onData(chunk, logStreams.out));
    if (child.stderr) child.stderr.on('data', (chunk) => onData(chunk, logStreams.err));
    child.once('error', (err) => {
      if (settled) return;
      settled = true;
      clearTimeout(timer);
      reject(err);
    });
    child.once('exit', (code) => {
      if (settled) return;
      settled = true;
      clearTimeout(timer);
      reject(readyError(`devtunnel host exited before becoming ready (${code}).`));
    });
  });
}

async function startMicrosoftDevTunnelHostAttempt(tunnelId, options = {}) {
  const hostHeaderMode = normalizeHostHeaderMode(options.hostHeaderMode || options.host_header_mode);
  const fsImpl = options.fs || fs;
  fsImpl.mkdirSync(setupDir(options), { recursive: true, mode: 0o700 });
  try { fsImpl.chmodSync(setupDir(options), 0o700); } catch {}
  const logDir = logsDir(options);
  fsImpl.mkdirSync(logDir, { recursive: true, mode: 0o700 });
  try { fsImpl.chmodSync(logDir, 0o700); } catch {}
  const logPath = path.join(logDir, `${tunnelId}.devtunnel.log`);
  const errorLogPath = path.join(logDir, `${tunnelId}.devtunnel.err`);
  resetProcessLogFiles([logPath, errorLogPath], options);
  const args = devTunnelHostArgs(tunnelId, { hostHeaderMode });
  const spawn = options.spawn || defaultSpawn;
  const child = spawn('devtunnel', args, {
    cwd: setupDir(options),
    detached: true,
    env: { ...process.env },
    stdio: ['ignore', 'pipe', 'pipe'],
  });
  const out = fsImpl.createWriteStream ? fsImpl.createWriteStream(logPath, { flags: 'a', mode: 0o600 }) : null;
  const err = fsImpl.createWriteStream ? fsImpl.createWriteStream(errorLogPath, { flags: 'a', mode: 0o600 }) : null;
  let urls;
  try {
    urls = await waitForHostReady(child, { out, err }, options);
  } catch (hostErr) {
    killProcessTree(child && child.pid, options);
    const tail = [
      readLogTail(logPath, options),
      readLogTail(errorLogPath, options),
    ].filter(Boolean).join('\n').slice(-LOG_TAIL_BYTES);
    if (tail && !hostErr.host_log_tail) hostErr.host_log_tail = tail;
    hostErr.host_header_mode = hostHeaderMode;
    try { if (out) out.end(); } catch {}
    try { if (err) err.end(); } catch {}
    throw hostErr;
  }
  const runCommand = command('devtunnel', args).display;
  const tunnelRenewal = options.tunnelRenewal || options.tunnel_renewal || {};
  const lastTunnelRenewedAt = tunnelRenewal.renewed_at || '';
  const accessRenewedAt = options.access && (options.access.renewed_at || (options.access.created ? options.access.checked_at : '')) || '';
  const previousEvents = (() => {
    try {
      const prev = loadManagedTunnelState(options);
      return prev && Array.isArray(prev.host_events) ? prev.host_events : [];
    } catch { return []; }
  })();
  const startedAtIso = new Date().toISOString();
  const state = {
    pid: child && child.pid ? child.pid : null,
    tunnel_id: tunnelId,
    desired_running: true,
    origin: urls.origin,
    mobile_url: urls.mobile_url,
    inspect_url: urls.inspect_url,
    log_path: logPath,
    error_log_path: errorLogPath,
    run_command: runCommand,
    host_header_mode: hostHeaderMode,
    header_passthrough: hostHeaderMode === HOST_HEADER_MODE_PASSTHROUGH,
    header_passthrough_fallback: !!options.headerPassthroughFallback,
    header_passthrough_fallback_reason: options.headerPassthroughFallbackReason || '',
    started_at: startedAtIso,
    stopped_at: '',
    last_restore_failed_at: '',
    restore_error: '',
    host_events: [...previousEvents, { at: startedAtIso, type: 'host_started', detail: urls.origin || '' }].slice(-HOST_EVENT_LIMIT),
    access_mode: options.access && options.access.mode || '',
    access: options.access || null,
    last_access_check_at: options.access && options.access.checked_at || '',
    last_access_renewed_at: accessRenewedAt,
    next_access_renewal_at: options.access && options.access.next_renewal_at || '',
    access_expiration: options.access && options.access.expiration || '',
    access_error: options.access && options.access.error || '',
    last_tunnel_renewed_at: lastTunnelRenewedAt,
    next_tunnel_renewal_at: tunnelRenewal.next_renewal_at || '',
    tunnel_expiration: tunnelRenewal.expiration || '',
    tunnel_renewal_error: tunnelRenewal.error || '',
  };
  writeManagedTunnelState(state, options);
  watchDevTunnelHostOutput(child, options);
  return { configured: true, running: !!state.pid, started: true, ...state, state_path: managedStatePath(options) };
}

async function startMicrosoftDevTunnelHost(tunnelId, options = {}) {
  try {
    return await startMicrosoftDevTunnelHostAttempt(tunnelId, {
      ...options,
      hostHeaderMode: HOST_HEADER_MODE_PASSTHROUGH,
    });
  } catch (err) {
    if (options.disableHeaderPassthroughFallback || !isHeaderPassthroughHostFailure(err)) throw err;
    const fallbackReason = hostStartFailureText(err).trim().slice(0, 800);
    return startMicrosoftDevTunnelHostAttempt(tunnelId, {
      ...options,
      hostHeaderMode: HOST_HEADER_MODE_DEFAULT,
      headerPassthroughFallback: true,
      headerPassthroughFallbackReason: fallbackReason,
    });
  }
}

async function applyMicrosoftDevTunnelSetup(input = {}, options = {}) {
  const detected = await detectMicrosoftDevTunnelSetup(options);
  if (!detected.installed) {
    return { ok: false, error_code: 'devtunnel_cli_missing', error: detected.error || 'Microsoft devtunnel CLI is not installed.', setup: detected };
  }
  if (!detected.signed_in) {
    return { ok: false, error_code: 'devtunnel_login_required', error: 'Sign in to Microsoft Dev Tunnels before starting the tunnel.', setup: detected };
  }

  const previous = loadManagedTunnelState(options) || {};
  const previousProcess = previous.pid ? await inspectManagedTunnelProcess(previous, options) : null;
  if (previousProcess && managedTunnelProcessUsable(previousProcess, previous) && previous.origin) {
    let persistent = null;
    try {
      persistent = await ensurePersistentTunnel(previous.tunnel_id, { ...options, input });
    } catch (err) {
      return {
        ok: false,
        error_code: err?.code === 'ENOENT' ? 'devtunnel_cli_missing' : 'devtunnel_access_failed',
        error: String(err?.stderr || err?.message || err || 'Microsoft dev tunnel access setup failed').slice(0, 800),
        setup: detected,
      };
    }
    const access = persistent && persistent.access;
    const managed = await detectManagedMicrosoftDevTunnel(options);
    return {
      ok: true,
      reused: true,
      tunnel_id: managed.tunnel_id,
      origin: managed.origin,
      mobile_url: managed.mobile_url,
      inspect_url: managed.inspect_url,
      managed_tunnel: {
        ...managed,
        access,
        access_mode: access.mode,
        last_access_check_at: access.checked_at,
        access_error: access.error || '',
        tunnel_renewal: persistent.tunnel_renewal,
      },
      traffic: getTrafficInspection(),
    };
  }
  if (previousProcess && previousProcess.running && !managedTunnelProcessUsable(previousProcess, previous)) {
    killProcessTree(previous.pid, options);
  }

  const requestedTunnelId = normalizeTunnelId(input.tunnel_id || input.tunnelId || previous.tunnel_id || '');
  const tunnelId = requestedTunnelId || createTunnelId();
  try {
    const persistent = await ensurePersistentTunnel(tunnelId, { ...options, input });
    const managed = await startMicrosoftDevTunnelHost(tunnelId, {
      ...options,
      access: persistent.access,
      tunnelRenewal: persistent.tunnel_renewal,
    });
    return {
      ok: true,
      reused: false,
      tunnel_id: tunnelId,
      origin: managed.origin,
      mobile_url: managed.mobile_url,
      inspect_url: managed.inspect_url,
      managed_tunnel: managed,
      traffic: getTrafficInspection(),
    };
  } catch (err) {
    return {
      ok: false,
      error_code: err?.code === 'ENOENT' ? 'devtunnel_cli_missing' : 'devtunnel_start_failed',
      error: String(err?.stderr || err?.message || err || 'Microsoft dev tunnel setup failed').slice(0, 800),
      setup: detected,
    };
  }
}

async function restoreMicrosoftDevTunnelHost(options = {}) {
  const state = loadManagedTunnelState(options);
  if (!state) {
    return { ok: true, restored: false, reason: 'not_configured', managed_tunnel: { configured: false, running: false } };
  }

  const managed = await detectManagedMicrosoftDevTunnel(options);
  if (managed.running && options.forceRestart === true) {
    killProcessTree(state.pid, options);
  } else if (managedTunnelProcessUsable(managed, state)) {
    const due = microsoftTunnelRenewalDue(state, options);
    let persistent = null;
    if (options.repairAccess === true || options.renewTunnel === true || options.renew_tunnel === true || options.renewAccess === true || options.renew_access === true || due.tunnel || due.access) {
      persistent = await ensurePersistentTunnel(state.tunnel_id, {
        ...options,
        accessMode: state.access_mode || state.access?.mode || options.accessMode || options.access_mode,
        renewTunnel: options.renewTunnel === true || options.renew_tunnel === true || due.tunnel,
        renewAccess: options.renewAccess === true || options.renew_access === true || due.access,
      });
    }
    const latest = await detectManagedMicrosoftDevTunnel(options);
    return {
      ok: true,
      restored: false,
      already_running: true,
      managed_tunnel: persistent && persistent.access
        ? {
          ...latest,
          access: persistent.access,
          access_mode: persistent.access.mode,
          last_access_check_at: persistent.access.checked_at,
          access_error: persistent.access.error || '',
          tunnel_renewal: persistent.tunnel_renewal,
        }
        : latest,
    };
  }
  if (managed.running && !managedTunnelProcessUsable(managed, state)) {
    killProcessTree(state.pid, options);
  }
  if (!managedTunnelDesiredRunning(state)) {
    return { ok: true, restored: false, reason: 'not_desired', managed_tunnel: managed };
  }

  const tunnelId = normalizeTunnelId(state.tunnel_id || '');
  if (!tunnelId) {
    return { ok: false, restored: false, error_code: 'missing_tunnel_id', error: 'Saved Microsoft dev tunnel state is missing a valid tunnel id.', managed_tunnel: managed };
  }

  const login = await detectLoginStatus(options);
  if (login.installed === false) {
    const nextState = {
      ...state,
      desired_running: true,
      last_restore_failed_at: new Date().toISOString(),
      restore_error: login.error || 'Microsoft devtunnel CLI is not installed or not on PATH.',
    };
    writeManagedTunnelState(nextState, options);
    return { ok: false, restored: false, error_code: 'devtunnel_cli_missing', error: nextState.restore_error, managed_tunnel: await detectManagedMicrosoftDevTunnel(options) };
  }
  if (!login.signed_in) {
    const nextState = {
      ...state,
      desired_running: true,
      last_restore_failed_at: new Date().toISOString(),
      restore_error: 'Dev Tunnels sign-in is required before CTM can restore the tunnel host.',
    };
    writeManagedTunnelState(nextState, options);
    return { ok: false, restored: false, error_code: 'devtunnel_login_required', error: nextState.restore_error, managed_tunnel: await detectManagedMicrosoftDevTunnel(options) };
  }

  try {
    const persistent = await ensurePersistentTunnel(tunnelId, {
      ...options,
      accessMode: state.access_mode || state.access?.mode || options.accessMode || options.access_mode,
    });
    const restored = await startMicrosoftDevTunnelHost(tunnelId, {
      ...options,
      access: persistent.access,
      tunnelRenewal: persistent.tunnel_renewal,
    });
    return { ok: true, restored: true, managed_tunnel: restored };
  } catch (err) {
    const nextState = {
      ...state,
      pid: null,
      desired_running: true,
      last_restore_failed_at: new Date().toISOString(),
      restore_error: String(err?.stderr || err?.message || err || 'Microsoft dev tunnel restore failed').slice(0, 800),
    };
    writeManagedTunnelState(nextState, options);
    return { ok: false, restored: false, error_code: err?.code === 'ENOENT' ? 'devtunnel_cli_missing' : 'devtunnel_restore_failed', error: nextState.restore_error, managed_tunnel: await detectManagedMicrosoftDevTunnel(options) };
  }
}

async function checkMicrosoftDevTunnelAvailability(options = {}) {
  const checkedAt = new Date().toISOString();
  const keepAwake = await reconcileMicrosoftDevTunnelKeepAwake(options);
  const state = loadManagedTunnelState(options);
  if (!state) {
    return {
      ok: true,
      checked: true,
      recovered: false,
      reason: 'not_configured',
      keep_awake: keepAwake,
      managed_tunnel: { configured: false, running: false },
    };
  }
  if (!managedTunnelDesiredRunning(state)) {
    await annotateWatchdogState({ last_watchdog_check_at: checkedAt, watchdog_error: '' }, options);
    return {
      ok: true,
      checked: true,
      recovered: false,
      reason: 'not_desired',
      keep_awake: await getMicrosoftDevTunnelKeepAwakeStatus(options),
      managed_tunnel: await detectManagedMicrosoftDevTunnel(options),
    };
  }

  const before = await detectManagedMicrosoftDevTunnel(options);
  await annotateWatchdogState({ last_watchdog_check_at: checkedAt, watchdog_error: '' }, options);
  if (managedTunnelProcessUsable(before, state)) {
    let managed = before;
    const due = microsoftTunnelRenewalDue(state, options);
    if (options.repairAccess === true || options.renewTunnel === true || options.renew_tunnel === true || options.renewAccess === true || options.renew_access === true || due.tunnel || due.access) {
      try {
        const persistent = await ensurePersistentTunnel(state.tunnel_id, {
          ...options,
          accessMode: state.access_mode || state.access?.mode || options.accessMode || options.access_mode,
          renewTunnel: options.renewTunnel === true || options.renew_tunnel === true || due.tunnel,
          renewAccess: options.renewAccess === true || options.renew_access === true || due.access,
        });
        const latest = await detectManagedMicrosoftDevTunnel(options);
        const access = persistent.access;
        managed = {
          ...latest,
          access,
          access_mode: access.mode,
          last_access_check_at: access.checked_at,
          access_error: access.error || '',
          tunnel_renewal: persistent.tunnel_renewal,
        };
      } catch (err) {
        const error = String(err?.stderr || err?.message || err || 'Microsoft tunnel access repair failed.').slice(0, 800);
        await annotateWatchdogState({ last_watchdog_check_at: checkedAt, watchdog_error: error, access_error: error }, options);
        return {
          ok: false,
          checked: true,
          recovered: false,
          reason: 'access_repair_failed',
          error,
          keep_awake: await getMicrosoftDevTunnelKeepAwakeStatus(options),
          managed_tunnel: await detectManagedMicrosoftDevTunnel(options),
        };
      }
    }
    if (options.verifyPublicAccess === true) {
      const probe = await probeMicrosoftDevTunnelPublicAccess({ managed_tunnel: managed }, {
        ...options,
        timeoutMs: options.publicProbeTimeoutMs || options.timeoutMs || PUBLIC_PROBE_TIMEOUT_MS,
      });
      managed = { ...managed, public_probe: probe };
      if (probe.ctm_reachable) {
        return {
          ok: true,
          checked: true,
          recovered: false,
          reason: 'running',
          keep_awake: await getMicrosoftDevTunnelKeepAwakeStatus(options),
          managed_tunnel: managed,
        };
      }
      if (probe.blocked_by_tunnel_auth) {
        if (managed.access?.mode === 'ctm_authenticated') {
          const error = probe.message || 'Microsoft Dev Tunnels is still requiring provider sign-in even though CTM-authenticated tunnel access is configured.';
          await annotateWatchdogState({ last_watchdog_check_at: checkedAt, watchdog_error: error }, options);
          return {
            ok: false,
            checked: true,
            recovered: false,
            reason: 'unexpected_tunnel_auth_gate',
            error,
            public_probe: probe,
            keep_awake: await getMicrosoftDevTunnelKeepAwakeStatus(options),
            managed_tunnel: managed,
          };
        }
        await annotateWatchdogState({ last_watchdog_check_at: checkedAt, watchdog_error: '' }, options);
        return {
          ok: true,
          checked: true,
          recovered: false,
          reason: 'private_tunnel_auth_required',
          public_probe: probe,
          keep_awake: await getMicrosoftDevTunnelKeepAwakeStatus(options),
          managed_tunnel: managed,
        };
      }
      const restarted = await restoreMicrosoftDevTunnelHost({ ...options, repairAccess: true, forceRestart: true });
      if (restarted.ok && restarted.managed_tunnel?.running) {
        await annotateWatchdogState({
          last_watchdog_check_at: checkedAt,
          last_watchdog_recovered_at: new Date().toISOString(),
          watchdog_error: '',
        }, options);
        return {
          ok: true,
          checked: true,
          recovered: true,
          reason: 'public_probe_restarted',
          public_probe: probe,
          keep_awake: await getMicrosoftDevTunnelKeepAwakeStatus(options),
          managed_tunnel: await detectManagedMicrosoftDevTunnel(options),
        };
      }
      const error = restarted.error || probe.message || 'Microsoft tunnel public URL did not reach CTM.';
      await annotateWatchdogState({ last_watchdog_check_at: checkedAt, watchdog_error: error }, options);
      return {
        ok: false,
        checked: true,
        recovered: false,
        reason: restarted.reason || restarted.error_code || probe.diagnosis || 'public_probe_failed',
        error,
        public_probe: probe,
        keep_awake: await getMicrosoftDevTunnelKeepAwakeStatus(options),
        managed_tunnel: await detectManagedMicrosoftDevTunnel(options),
      };
    }
    return {
      ok: true,
      checked: true,
      recovered: false,
      reason: 'running',
      keep_awake: await getMicrosoftDevTunnelKeepAwakeStatus(options),
      managed_tunnel: managed,
    };
  }

  const result = await restoreMicrosoftDevTunnelHost(options);
  if (result.ok && result.managed_tunnel?.running) {
    await annotateWatchdogState({
      last_watchdog_check_at: checkedAt,
      last_watchdog_recovered_at: new Date().toISOString(),
      watchdog_error: '',
    }, options);
    return {
      ok: true,
      checked: true,
      recovered: !!result.restored,
      reason: result.restored ? 'restored' : (result.reason || 'already_running'),
      keep_awake: await getMicrosoftDevTunnelKeepAwakeStatus(options),
      managed_tunnel: await detectManagedMicrosoftDevTunnel(options),
    };
  }

  const error = result.error || 'Microsoft tunnel recovery failed.';
  await annotateWatchdogState({
    last_watchdog_check_at: checkedAt,
    watchdog_error: error,
  }, options);
  return {
    ok: false,
    checked: true,
    recovered: false,
    reason: result.reason || result.error_code || 'restore_failed',
    error,
    keep_awake: await getMicrosoftDevTunnelKeepAwakeStatus(options),
    managed_tunnel: await detectManagedMicrosoftDevTunnel(options),
  };
}

async function stopMicrosoftDevTunnel(options = {}) {
  const state = loadManagedTunnelState(options);
  await disableMicrosoftDevTunnelKeepAwake(options);
  if (!state) return { ok: true, stopped: false, keep_awake: await getMicrosoftDevTunnelKeepAwakeStatus(options), managed_tunnel: { configured: false, running: false } };
  if (!state.pid) {
    const nextState = { ...state, desired_running: false, stopped_at: new Date().toISOString() };
    writeManagedTunnelState(nextState, options);
    return {
      ok: true,
      stopped: false,
      keep_awake: await getMicrosoftDevTunnelKeepAwakeStatus(options),
      managed_tunnel: { ...nextState, configured: true, running: false, state_path: managedStatePath(options) },
    };
  }
  const inspected = await inspectManagedTunnelProcess(state, options);
  const stopped = inspected.running ? killProcessTree(state.pid, options) : false;
  const nextState = {
    ...state,
    pid: null,
    desired_running: false,
    stopped_at: new Date().toISOString(),
    stale_pid: inspected.stale_pid || undefined,
  };
  writeManagedTunnelState(nextState, options);
  return {
    ok: true,
    stopped,
    keep_awake: await getMicrosoftDevTunnelKeepAwakeStatus(options),
    managed_tunnel: {
      ...nextState,
      configured: true,
      running: false,
      pid_running: !!inspected.pid_running,
      process_verified: false,
      state_path: managedStatePath(options),
    },
  };
}

function stopLoginProcessState(state, options = {}) {
  if (!state || !state.pid) return false;
  const stopped = killProcessTree(state.pid, options);
  try {
    writeLoginProcessState({ ...state, running: false, stopped_at: new Date().toISOString() }, options);
  } catch {}
  return stopped;
}

function loginStateProvider(state = {}) {
  if (state.provider) return normalizeLoginProvider({ provider: state.provider });
  return /\s-g(?:\s|$)/.test(String(state.command || '')) ? 'github' : 'microsoft';
}

function loginStateIsReusable(state, provider, options = {}) {
  if (!state || state.error_code || state.error) return false;
  if (loginStateProvider(state) !== provider) return false;
  if (!state.running || !pidIsRunning(state.pid)) return false;
  const started = Date.parse(state.started_at || '');
  if (!Number.isFinite(started)) return false;
  const now = Number(options.nowMs || Date.now());
  return now - started < Number(options.loginReuseMs || LOGIN_REUSE_MS);
}

async function logoutMicrosoftDevTunnelUser(options = {}) {
  const previous = loadLoginProcessState(options);
  if (previous && previous.running && pidIsRunning(previous.pid)) {
    stopLoginProcessState(previous, options);
  }

  const execFile = options.execFile || defaultExecFile;
  const args = ['user', 'logout'];
  // Keep the provider the user last signed in with so the next sign-in (and the
  // one-click Reconnect action) defaults to the same account type.
  const previousProvider = loginStateProvider(previous || {});
  const baseState = {
    ...(previous || {}),
    running: false,
    pid: null,
    provider: previousProvider,
    provider_label: loginProviderLabel(previousProvider),
    command: command('devtunnel', args).display,
    login_url: '',
    device_code: '',
    error: '',
    error_code: '',
    signed_out_at: new Date().toISOString(),
  };
  try {
    const result = await execFile('devtunnel', args, {
      encoding: 'utf8',
      timeout: options.commandTimeoutMs || 15000,
      maxBuffer: 512 * 1024,
    });
    const stoppedTunnel = options.stopTunnel === false ? null : await stopMicrosoftDevTunnel(options).catch((err) => ({
      ok: false,
      error: String(err?.message || err || 'Could not stop existing Microsoft tunnel').slice(0, 800),
    }));
    const nextState = {
      ...baseState,
      stdout: String(result?.stdout || '').trim().slice(0, 800),
      stderr: String(result?.stderr || '').trim().slice(0, 800),
    };
    writeLoginProcessState(nextState, options);
    return {
      ok: true,
      already_signed_out: false,
      stopped_tunnel: stoppedTunnel,
      logout: { ...nextState, state_path: loginStatePath(options) },
      setup: await detectMicrosoftDevTunnelSetup(options),
      progress: getMicrosoftDevTunnelProgress(options),
    };
  } catch (err) {
    const text = String(`${err?.stdout || ''}\n${err?.stderr || ''}\n${err?.message || ''}`);
    const alreadySignedOut = /not\s+(?:logged|signed)\s+in|no\s+user|login\s+required/i.test(text);
    const nextState = {
      ...baseState,
      already_signed_out: alreadySignedOut,
      error_code: alreadySignedOut ? '' : (err?.code === 'ENOENT' ? 'devtunnel_cli_missing' : 'devtunnel_logout_failed'),
      error: alreadySignedOut ? '' : text.trim().slice(0, 800),
    };
    writeLoginProcessState(nextState, options);
    if (alreadySignedOut) {
      const stoppedTunnel = options.stopTunnel === false ? null : await stopMicrosoftDevTunnel(options).catch((stopErr) => ({
        ok: false,
        error: String(stopErr?.message || stopErr || 'Could not stop existing Microsoft tunnel').slice(0, 800),
      }));
      return {
        ok: true,
        already_signed_out: true,
        stopped_tunnel: stoppedTunnel,
        logout: { ...nextState, state_path: loginStatePath(options) },
        setup: await detectMicrosoftDevTunnelSetup(options),
        progress: getMicrosoftDevTunnelProgress(options),
      };
    }
    return {
      ok: false,
      already_signed_out: false,
      error_code: nextState.error_code,
      error: nextState.error || 'Microsoft Dev Tunnels sign-out failed.',
      logout: { ...nextState, state_path: loginStatePath(options) },
      setup: await detectMicrosoftDevTunnelSetup(options).catch(() => null),
      progress: getMicrosoftDevTunnelProgress(options),
    };
  }
}

function startMicrosoftDevTunnelLogin(input = {}, options = {}) {
  const fsImpl = options.fs || fs;
  fsImpl.mkdirSync(setupDir(options), { recursive: true, mode: 0o700 });
  const logDir = logsDir(options);
  fsImpl.mkdirSync(logDir, { recursive: true, mode: 0o700 });
  const logPath = path.join(logDir, 'devtunnel-login.log');
  const errorLogPath = path.join(logDir, 'devtunnel-login.err');
  // No explicit provider (e.g. the one-click Reconnect health action) → stick to
  // the last-used provider instead of silently switching account types.
  const requestedProvider = String(input.provider || '').trim() || (input.github === true ? 'github' : '');
  const provider = requestedProvider
    ? normalizeLoginProvider({ provider: requestedProvider })
    : loginStateProvider(loadLoginProcessState(options) || {});
  const forceNew = input.force_new === true || input.forceNew === true || input.regenerate === true;
  const previous = loadLoginProcessState(options);
  if (!forceNew && loginStateIsReusable(previous, provider, options)) {
    const login = processProgressFromState(previous, options);
    return {
      ok: true,
      reused: true,
      login,
      progress: getMicrosoftDevTunnelProgress(options),
    };
  }
  if (previous && previous.running && pidIsRunning(previous.pid)) {
    stopLoginProcessState(previous, options);
  }
  resetProcessLogFiles([logPath, errorLogPath], options);
  const args = ['user', 'login'];
  args.push(...loginProviderArgs(provider));
  const useDeviceCode = input.device_code !== false && input.deviceCode !== false;
  if (useDeviceCode) args.push('-d');
  const spawn = options.spawn || defaultSpawn;
  const child = spawn('devtunnel', args, {
    cwd: setupDir(options),
    detached: true,
    env: { ...process.env },
    stdio: ['ignore', 'pipe', 'pipe'],
  });
  const out = fsImpl.createWriteStream ? fsImpl.createWriteStream(logPath, { flags: 'a', mode: 0o600 }) : null;
  const err = fsImpl.createWriteStream ? fsImpl.createWriteStream(errorLogPath, { flags: 'a', mode: 0o600 }) : null;
  const state = {
    pid: child && child.pid ? child.pid : null,
    running: !!(child && child.pid),
    provider,
    provider_label: loginProviderLabel(provider),
    command: command('devtunnel', args).display,
    log_path: logPath,
    error_log_path: errorLogPath,
    started_at: new Date().toISOString(),
  };
  writeLoginProcessState(state, options);
  let current = state;
  let combined = '';
  function update(partial) {
    current = { ...current, ...partial };
    writeLoginProcessState(current, options);
  }
  function onData(chunk, stream) {
    const text = String(chunk || '');
    combined += text;
    if (stream && !stream.destroyed) stream.write(text);
    const hints = parseDevTunnelLoginHints(combined);
    const failure = devTunnelLoginError(combined);
    let next = { ...hints, ...failure };
    if (hints.login_url) next = openLoginUrl(hints.login_url, { ...current, ...next }, options);
    update(next);
  }
  if (child.stdout) child.stdout.on('data', (chunk) => onData(chunk, out));
  if (child.stderr) child.stderr.on('data', (chunk) => onData(chunk, err));
  child.once('error', (spawnErr) => {
    update({ running: false, error: String(spawnErr?.message || spawnErr || 'Login failed').slice(0, 800), finished_at: new Date().toISOString() });
    try { if (out) out.end(); } catch {}
    try { if (err) err.end(); } catch {}
  });
  child.once('exit', (code, signal) => {
    update({ running: false, exit_code: code, signal: signal || '', finished_at: new Date().toISOString() });
    try { if (out) out.end(); } catch {}
    try { if (err) err.end(); } catch {}
    if (code === 0) {
      checkMicrosoftDevTunnelLoginStatus({ ...options, includeSetup: false }).catch((loginErr) => {
        update({ login_check_error: String(loginErr?.message || loginErr || 'Could not verify Dev Tunnels sign-in').slice(0, 800) });
      });
    }
  });
  return {
    ok: true,
    login: { ...current, state_path: loginStatePath(options) },
    progress: getMicrosoftDevTunnelProgress(options),
  };
}

module.exports = {
  appendManagedTunnelHostEvent,
  applyMicrosoftDevTunnelSetup,
  checkMicrosoftDevTunnelAvailability,
  checkMicrosoftDevTunnelLoginStatus,
  classifyDevTunnelHostEventText,
  clearMicrosoftDevTunnelTraffic,
  command,
  detectManagedMicrosoftDevTunnel,
  detectMicrosoftDevTunnelSetup,
  disableMicrosoftDevTunnelKeepAwake,
  enableMicrosoftDevTunnelKeepAwake,
  getMicrosoftDevTunnelKeepAwakeStatus,
  getMicrosoftDevTunnelProgress,
  getTrafficInspection,
  installMicrosoftDevTunnelCli,
  inspectMicrosoftTunnelAccess,
  inspectKeepAwakeProcess,
  startMicrosoftDevTunnelInstall,
  inspectManagedTunnelProcess,
  loadKeepAwakeState,
  loadManagedTunnelState,
  loadLoginProcessState,
  loginProviderArgs,
  loginProviderLabel,
  loginStateProvider,
  logoutMicrosoftDevTunnelUser,
  managedTunnelDesiredRunning,
  microsoftDevTunnelCommands,
  microsoftTunnelPrivateAccessForced,
  normalizeMicrosoftTunnelAccessMode,
  normalizeTunnelId,
  resolveMicrosoftTunnelAccessMode,
  parseDevTunnelAccessEntries,
  parseDevTunnelUrls,
  parseDevTunnelLoginHints,
  parseDevTunnelUserShow,
  hasAnonymousConnectAccess,
  pidIsRunning,
  probeMicrosoftDevTunnelPublicAccess,
  recordMicrosoftDevTunnelTraffic,
  resetMicrosoftDevTunnelPrivateAccess,
  restoreMicrosoftDevTunnelHost,
  sanitizeRequestPath,
  setMicrosoftDevTunnelKeepAwake,
  startMicrosoftDevTunnelLogin,
  stopMicrosoftDevTunnel,
  WATCHDOG_CHECK_INTERVAL_MS,
  WATCHDOG_WAKE_DRIFT_MS,
};
