/**
 * Debug Wrapper Entry Point
 * Wraps the existing hytale-auth-server with debug capabilities
 */

const http = require('http');
const https = require('https');
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');

// Only load debug functionality if DEBUG_MODE is enabled
const DEBUG_MODE = process.env.DEBUG_MODE === 'true';

const DATA_DIR = process.env.DATA_DIR || '/app/data';
const LOG_FILE = path.join(DATA_DIR, 'debug-requests.jsonl');
const SSL_DIR = path.join(DATA_DIR, 'ssl');
const SSL_KEY = path.join(SSL_DIR, 'server.key');
const SSL_CERT = path.join(SSL_DIR, 'server.crt');
const HTTPS_PORT = parseInt(process.env.HTTPS_PORT || '3443');

/**
 * Generate self-signed SSL certificates if they don't exist
 */
function ensureSSLCertificates() {
  if (!fs.existsSync(SSL_DIR)) {
    fs.mkdirSync(SSL_DIR, { recursive: true });
  }

  if (!fs.existsSync(SSL_KEY) || !fs.existsSync(SSL_CERT)) {
    console.log('Generating self-signed SSL certificates...');
    try {
      execSync(`openssl req -x509 -newkey rsa:2048 -keyout "${SSL_KEY}" -out "${SSL_CERT}" -days 365 -nodes -subj "/CN=localhost" 2>/dev/null`);
      console.log('SSL certificates generated successfully');
    } catch (err) {
      console.error('Failed to generate SSL certificates:', err.message);
      console.error('HTTPS will not be available. Install openssl or provide certificates manually.');
      return null;
    }
  }

  try {
    return {
      key: fs.readFileSync(SSL_KEY),
      cert: fs.readFileSync(SSL_CERT)
    };
  } catch (err) {
    console.error('Failed to read SSL certificates:', err.message);
    return null;
  }
}

// In-memory request storage for debug dashboard
const capturedRequests = [];
const MAX_CAPTURED = 500;

// Color codes for terminal output
const colors = {
  reset: '\x1b[0m',
  green: '\x1b[32m',
  blue: '\x1b[34m',
  yellow: '\x1b[33m',
  magenta: '\x1b[35m',
  cyan: '\x1b[36m',
  red: '\x1b[31m'
};

function extractSubdomain(host) {
  if (!host) return null;
  const hostname = host.split(':')[0];
  const match = hostname.match(/^(sessions|account-data|telemetry|tools|oauth\.accounts|accounts)\./);
  return match ? match[1] : null;
}

function getSubdomainColor(subdomain) {
  const subColors = {
    'sessions': colors.green,
    'account-data': colors.blue,
    'telemetry': colors.yellow,
    'tools': colors.magenta
  };
  return subColors[subdomain] || colors.cyan;
}

/**
 * Serve the debug dashboard HTML
 */
function serveDebugDashboard(res) {
  const html = `<!DOCTYPE html>
<html><head><title>Debug Dashboard - Local Dev</title>
<style>
body{font-family:monospace;background:#1a1a2e;color:#eee;padding:20px;margin:0}
h1{color:#00d4ff;margin-bottom:10px}
.info{color:#888;font-size:12px;margin-bottom:20px}
.section{background:#16213e;padding:15px;margin:10px 0;border-radius:8px}
.req{background:#0f3460;padding:10px;margin:5px 0;border-radius:4px;font-size:12px;border-left:3px solid #00d4ff}
.req.error{border-left-color:#f87171}
.GET{color:#4ade80}.POST{color:#60a5fa}.DELETE{color:#f87171}.PUT{color:#fbbf24}
.sub{color:#c084fc;font-weight:bold}
.status{padding:2px 6px;border-radius:3px;font-size:11px}
.status.ok{background:#166534;color:#4ade80}
.status.error{background:#7f1d1d;color:#f87171}
pre{background:#0a0a1a;padding:10px;overflow-x:auto;font-size:11px;border-radius:4px;max-height:300px;overflow-y:auto}
button{background:#00d4ff;color:#000;border:none;padding:8px 16px;cursor:pointer;margin:4px;border-radius:4px;font-weight:bold}
button:hover{background:#00b8e6}
button.danger{background:#dc2626}
button.danger:hover{background:#b91c1c}
button.paused{background:#fbbf24;color:#000}
select{padding:8px;background:#0f3460;border:1px solid #00d4ff;color:#fff;border-radius:4px}
details summary{cursor:pointer;color:#60a5fa;padding:5px 0}
.timestamp{color:#666;font-size:10px}
.duration{color:#fbbf24}
.path{color:#fff}
#count{margin-left:10px;color:#4ade80}
#pauseStatus{margin-left:10px;color:#fbbf24;font-weight:bold}
.controls{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
</style></head><body>
<h1>Debug Dashboard - Local Development</h1>
<div class="info">Capturing all requests to auth server for research purposes</div>

<div class="section">
  <div class="controls">
    <button onclick="refresh()">Refresh</button>
    <button id="pauseBtn" onclick="togglePause()">Pause</button>
    <button class="danger" onclick="clearReqs()">Clear All</button>
    <select id="filter" onchange="refresh()">
      <option value="">All Subdomains</option>
      <option value="sessions">sessions</option>
      <option value="account-data">account-data</option>
      <option value="telemetry">telemetry</option>
      <option value="tools">tools</option>
      <option value="main">main (no subdomain)</option>
    </select>
    <span id="count"></span>
    <span id="pauseStatus"></span>
  </div>
</div>

<div class="section">
  <h2>Subdomain Summary</h2>
  <div id="subs"></div>
</div>

<div class="section">
  <h2>Recent Requests</h2>
  <div id="reqs" style="max-height:600px;overflow-y:auto"></div>
</div>

<script>
let isPaused = false;
let refreshInterval = null;

async function refresh() {
  const f = document.getElementById('filter').value;
  const r = await fetch('/debug/requests' + (f ? '?subdomain=' + f : ''));
  const d = await r.json();
  document.getElementById('count').textContent = d.total + ' total, ' + d.filtered + ' shown';

  document.getElementById('reqs').innerHTML = d.requests.map((r, i) => {
    const statusClass = r.response?.statusCode >= 400 ? 'error' : 'ok';
    const reqClass = r.response?.statusCode >= 400 ? 'error' : '';
    return \`<div class="req \${reqClass}">
      <div>
        <span class="timestamp">\${r.timestamp}</span>
        <span class="\${r.method}">\${r.method}</span>
        <span class="sub">\${r.subdomain || 'main'}</span>
        <span class="path">\${r.path}</span>
        <span class="status \${statusClass}">\${r.response?.statusCode || '?'}</span>
        <span class="duration">\${r.response?.duration || 0}ms</span>
      </div>
      <details ontoggle="handleDetailsToggle(this)">
        <summary>Request Details</summary>
        <pre>\${JSON.stringify({
          host: r.host,
          query: r.query,
          body: r.body,
          headers: r.headers
        }, null, 2)}</pre>
      </details>
      <details ontoggle="handleDetailsToggle(this)">
        <summary>Response</summary>
        <pre>\${JSON.stringify(r.response, null, 2)}</pre>
      </details>
    </div>\`;
  }).join('');

  const s = await fetch('/debug/subdomains');
  const sd = await s.json();
  document.getElementById('subs').innerHTML = Object.entries(sd)
    .map(([k, v]) => '<span class="sub">' + k + '</span>: ' + v.count)
    .join(' | ') || '<em>No requests yet</em>';
}

function handleDetailsToggle(el) {
  // Auto-pause when any details block is opened
  if (el.open && !isPaused) {
    togglePause();
  }
}

function togglePause() {
  isPaused = !isPaused;
  const btn = document.getElementById('pauseBtn');
  const status = document.getElementById('pauseStatus');
  if (isPaused) {
    btn.textContent = 'Resume';
    btn.classList.add('paused');
    status.textContent = '(auto-refresh paused)';
    if (refreshInterval) {
      clearInterval(refreshInterval);
      refreshInterval = null;
    }
  } else {
    btn.textContent = 'Pause';
    btn.classList.remove('paused');
    status.textContent = '';
    refreshInterval = setInterval(autoRefresh, 3000);
    refresh();
  }
}

function autoRefresh() {
  if (!isPaused) {
    refresh();
  }
}

async function clearReqs() {
  if (confirm('Clear all captured requests?')) {
    await fetch('/debug/requests', { method: 'DELETE' });
    refresh();
  }
}

refreshInterval = setInterval(autoRefresh, 3000);
refresh();
</script>
</body></html>`;

  res.writeHead(200, { 'Content-Type': 'text/html' });
  res.end(html);
}

/**
 * Handle debug API endpoints
 */
function handleDebugApi(req, res, urlPath, url) {
  if (urlPath === '/debug' || urlPath === '/debug/') {
    serveDebugDashboard(res);
    return true;
  }

  if (urlPath === '/debug/requests') {
    if (req.method === 'DELETE') {
      capturedRequests.length = 0;
      res.writeHead(200, { 'Content-Type': 'application/json' });
      res.end(JSON.stringify({ cleared: true }));
      return true;
    }

    let filtered = capturedRequests;
    const subdomain = url.searchParams.get('subdomain');
    if (subdomain) {
      if (subdomain === 'main') {
        filtered = filtered.filter(r => !r.subdomain);
      } else {
        filtered = filtered.filter(r => r.subdomain === subdomain);
      }
    }

    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({
      total: capturedRequests.length,
      filtered: filtered.length,
      requests: filtered.slice(0, 100)
    }));
    return true;
  }

  if (urlPath === '/debug/subdomains') {
    const summary = {};
    for (const r of capturedRequests) {
      const sub = r.subdomain || 'main';
      if (!summary[sub]) summary[sub] = { count: 0 };
      summary[sub].count++;
    }
    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify(summary));
    return true;
  }

  return false;
}

/**
 * Capture request/response for debugging
 */
function captureRequest(req, res, url, startTime) {
  const subdomain = extractSubdomain(req.headers.host);
  const originalEnd = res.end.bind(res);
  let responseBody = null;

  // Intercept res.end to capture response
  res.end = function(chunk, encoding, callback) {
    if (chunk) {
      try {
        const str = chunk.toString();
        if (str.length > 2000) {
          responseBody = { _truncated: true, _length: str.length, _preview: str.substring(0, 500) };
        } else {
          try {
            responseBody = JSON.parse(str);
          } catch {
            responseBody = str;
          }
        }
      } catch (e) {
        responseBody = { _error: 'Could not capture response' };
      }
    }

    const duration = Date.now() - startTime;

    // Log with colors
    const subColor = getSubdomainColor(subdomain);
    const statusColor = res.statusCode >= 400 ? colors.red : colors.green;
    console.log(`${subColor}[${subdomain || 'main'}]${colors.reset} ${req.method} ${url.pathname} ${statusColor}${res.statusCode}${colors.reset} (${duration}ms)`);

    // Store in memory
    const entry = {
      timestamp: new Date().toISOString(),
      method: req.method,
      path: url.pathname,
      host: req.headers.host,
      subdomain,
      query: Object.fromEntries(url.searchParams),
      headers: sanitizeHeaders(req.headers),
      response: {
        statusCode: res.statusCode,
        duration,
        body: responseBody
      }
    };

    capturedRequests.unshift(entry);
    if (capturedRequests.length > MAX_CAPTURED) {
      capturedRequests.pop();
    }

    // Also write to file
    try {
      fs.appendFileSync(LOG_FILE, JSON.stringify(entry) + '\n');
    } catch (e) {
      // Ignore file write errors
    }

    return originalEnd(chunk, encoding, callback);
  };
}

/**
 * Sanitize headers for logging (remove sensitive data)
 */
function sanitizeHeaders(headers) {
  const sanitized = { ...headers };
  // Keep Authorization header but might want to truncate in future
  return sanitized;
}

/**
 * Main entry point - wraps the existing server
 */
async function main() {
  if (DEBUG_MODE) {
    console.log('\x1b[33m=== DEBUG MODE ENABLED ===\x1b[0m');
    console.log(`Debug dashboard: http://localhost:${process.env.PORT || 3000}/debug`);
    console.log(`Request log: ${LOG_FILE}`);
    console.log('');
  }

  // Load the original app module
  const app = require('./app');

  // If not debug mode, just run normally
  if (!DEBUG_MODE) {
    app.run();
    return;
  }

  // In debug mode, we need to wrap the request handler
  // Re-implement the server startup with debug wrapper
  const config = require('./config');
  const { connect: connectRedis, isConnected } = require('./services/redis');
  const assets = require('./services/assets');

  console.log('=== Hytale Auth Server (Debug Mode) ===');
  console.log(`Domain: ${config.domain}`);
  console.log(`Data directory: ${config.dataDir}`);

  // Pre-load cosmetics
  assets.preloadCosmetics();

  // Connect to Redis
  await connectRedis();

  // Create the original request handler reference
  const originalHandler = require('./app').handleRequest || null;

  // Since handleRequest is not exported, we need a different approach
  // Load all the modules manually
  const middleware = require('./middleware');
  const routes = require('./routes');
  const { sendJson } = require('./utils/response');
  const auth = require('./services/auth');
  const crypto = require('crypto');

  // Recreate the request handler with debug wrapping
  async function debugWrappedHandler(req, res) {
    const startTime = Date.now();
    const url = new URL(req.url, `http://${req.headers.host}`);
    const urlPath = url.pathname;

    // Skip debug endpoints from capture (but still handle them)
    if (urlPath.startsWith('/debug')) {
      if (handleDebugApi(req, res, urlPath, url)) {
        return;
      }
    }

    // Skip favicon and health from debug capture
    const skipCapture = urlPath === '/favicon.ico' || urlPath === '/health';

    // Capture the request/response if not skipped
    if (!skipCapture) {
      captureRequest(req, res, url, startTime);
    }

    // Now delegate to original handling logic
    // CORS headers
    middleware.corsHeaders(res);

    if (req.method === 'OPTIONS') {
      middleware.handleOptions(req, res);
      return;
    }

    // Handle binary uploads
    const headCacheMatch = urlPath.match(/^\/avatar\/([^/]+)\/head-cache$/);
    if (headCacheMatch && req.method === 'POST') {
      routes.avatar.handleAvatarRoutes(req, res, urlPath, {});
      return;
    }

    // Parse JSON body
    const body = await middleware.parseBody(req);

    // Store body for debug capture
    if (!skipCapture && capturedRequests.length > 0 && !capturedRequests[0].body) {
      capturedRequests[0].body = body;
    }

    // Extract user context
    const { uuid, name, tokenScope } = middleware.extractUserContext(body, req.headers);

    // Route the request (copied from app.js to avoid modification)
    await routeRequestDebug(req, res, url, urlPath, body, uuid, name, tokenScope, middleware, routes, sendJson, auth, crypto);
  }

  // Create HTTP server with debug wrapper
  const server = http.createServer(debugWrappedHandler);
  server.listen(config.port, '0.0.0.0', () => {
    console.log(`HTTP Server running on port ${config.port}`);
    console.log(`Redis: ${isConnected() ? 'connected' : 'NOT CONNECTED'}`);
    console.log(`\n\x1b[36mDebug Dashboard: http://localhost:${config.port}/debug\x1b[0m`);
  });

  // Create HTTPS server if certificates are available
  const sslOptions = ensureSSLCertificates();
  if (sslOptions) {
    const httpsServer = https.createServer(sslOptions, debugWrappedHandler);
    httpsServer.listen(HTTPS_PORT, '0.0.0.0', () => {
      console.log(`\x1b[32mHTTPS Server running on port ${HTTPS_PORT}\x1b[0m`);
      console.log(`\x1b[33mNote: Self-signed cert - add to keychain or use NODE_TLS_REJECT_UNAUTHORIZED=0\x1b[0m\n`);
    });
  }
}

/**
 * Route request - copied from app.js to avoid modifying original
 */
async function routeRequestDebug(req, res, url, urlPath, body, uuid, name, tokenScope, middleware, routes, sendJson, auth, crypto) {
  const headers = req.headers;

  // Avatar viewer routes
  if (urlPath.startsWith('/avatar/')) {
    await routes.avatar.handleAvatarRoutes(req, res, urlPath, body);
    return;
  }

  // Customizer route
  if (urlPath.startsWith('/customizer')) {
    routes.avatar.handleCustomizerRoute(req, res, urlPath);
    return;
  }

  // Cosmetics list API
  if (urlPath === '/cosmetics/list') {
    routes.assets.handleCosmeticsList(req, res);
    return;
  }

  // Single cosmetic item data API
  if (urlPath.startsWith('/cosmetics/item/')) {
    routes.assets.handleCosmeticItem(req, res, urlPath);
    return;
  }

  // Static assets route
  if (urlPath.startsWith('/assets/')) {
    routes.assets.handleStaticAssets(req, res, urlPath);
    return;
  }

  // Asset extraction route
  if (urlPath.startsWith('/asset/')) {
    routes.assets.handleAssetRoute(req, res, urlPath);
    return;
  }

  // Download route
  if (urlPath.startsWith('/download/')) {
    routes.assets.handleDownload(req, res, urlPath);
    return;
  }

  // Health check
  if (urlPath === '/health' || urlPath === '/') {
    routes.health.handleHealth(req, res);
    return;
  }

  // Favicon
  if (urlPath === '/favicon.ico') {
    res.writeHead(204);
    res.end();
    return;
  }

  // JWKS endpoint
  if (urlPath === '/.well-known/jwks.json' || urlPath === '/jwks.json') {
    routes.health.handleJwks(req, res);
    return;
  }

  // Server auto-auth
  if (urlPath === '/server/auto-auth') {
    routes.server.handleServerAutoAuth(req, res, body);
    return;
  }

  // Server game profiles
  if (urlPath === '/server/game-profiles' || urlPath === '/game-profiles') {
    routes.server.handleServerGameProfiles(req, res, headers);
    return;
  }

  // OAuth device authorization
  if (urlPath === '/oauth2/device/auth') {
    routes.server.handleOAuthDeviceAuth(req, res, body);
    return;
  }

  // OAuth device verification
  if (urlPath === '/oauth2/device/verify') {
    const query = Object.fromEntries(url.searchParams);
    routes.server.handleOAuthDeviceVerify(req, res, query);
    return;
  }

  // OAuth token endpoint
  if (urlPath === '/oauth2/token') {
    routes.server.handleOAuthToken(req, res, body);
    return;
  }

  // Game session endpoints
  if (urlPath === '/game-session/new') {
    routes.session.handleGameSessionNew(req, res, body, uuid, name);
    return;
  }

  if (urlPath === '/game-session/refresh') {
    await routes.session.handleGameSessionRefresh(req, res, body, uuid, name, headers);
    return;
  }

  if (urlPath === '/game-session/child' || urlPath.includes('/game-session/child')) {
    routes.session.handleGameSessionChild(req, res, body, uuid, name);
    return;
  }

  // Authorization grant
  if (urlPath === '/game-session/authorize' || urlPath.includes('/authorize') || urlPath.includes('/auth-grant')) {
    routes.session.handleAuthorizationGrant(req, res, body, uuid, name, headers);
    return;
  }

  // Token exchange
  if (urlPath === '/server-join/auth-token' || urlPath === '/game-session/exchange' || urlPath.includes('/auth-token')) {
    routes.session.handleTokenExchange(req, res, body, uuid, name, headers);
    return;
  }

  // Session/Auth endpoints
  if ((urlPath.includes('/session') || urlPath.includes('/child')) && !urlPath.startsWith('/admin')) {
    routes.session.handleSession(req, res, body, uuid, name);
    return;
  }

  if (urlPath.includes('/auth')) {
    routes.session.handleAuth(req, res, body, uuid, name);
    return;
  }

  if (urlPath.includes('/token')) {
    routes.session.handleToken(req, res, body, uuid, name);
    return;
  }

  if (urlPath.includes('/validate') || urlPath.includes('/verify')) {
    routes.session.handleValidate(req, res, body, uuid, name);
    return;
  }

  if (urlPath.includes('/refresh')) {
    routes.session.handleRefresh(req, res, body, uuid, name);
    return;
  }

  // Account data endpoints
  if (urlPath === '/my-account/game-profile' || urlPath.includes('/game-profile')) {
    await routes.account.handleGameProfile(req, res, body, uuid, name);
    return;
  }

  if (urlPath === '/my-account/skin') {
    await routes.account.handleSkin(req, res, body, uuid, name, routes.avatar.invalidateHeadCache);
    return;
  }

  // Account-data skin endpoint
  if (urlPath.startsWith('/account-data/skin/')) {
    const skinUuid = urlPath.replace('/account-data/skin/', '');
    await routes.account.handleSkin(req, res, body, skinUuid, name, routes.avatar.invalidateHeadCache);
    return;
  }

  if (urlPath === '/my-account/cosmetics' || urlPath.includes('/my-account/cosmetics')) {
    routes.account.handleCosmetics(req, res, body, uuid, name);
    return;
  }

  if (urlPath === '/my-account/get-launcher-data') {
    routes.account.handleLauncherData(req, res, body, uuid, name);
    return;
  }

  if (urlPath === '/my-account/get-profiles') {
    routes.account.handleGetProfiles(req, res, body, uuid, name);
    return;
  }

  // Bug reports and feedback
  if (urlPath === '/bugs/create' || urlPath === '/feedback/create') {
    res.writeHead(204);
    res.end();
    return;
  }

  // Game session delete
  if (urlPath === '/game-session' && req.method === 'DELETE') {
    await routes.session.handleGameSessionDelete(req, res, headers);
    return;
  }

  // Admin login
  if (urlPath === '/admin/login' && req.method === 'POST') {
    await routes.admin.handleAdminLogin(req, res, body);
    return;
  }

  // Admin verify
  if (urlPath === '/admin/verify') {
    const token = headers['x-admin-token'] || url.searchParams.get('token');
    await routes.admin.handleAdminVerify(req, res, token);
    return;
  }

  // Admin dashboard
  if (urlPath === '/admin' || urlPath === '/admin/') {
    routes.admin.handleAdminDashboard(req, res);
    return;
  }

  // Test page for head embed
  if (urlPath === '/test/head') {
    routes.avatar.handleTestHeadPage(req, res);
    return;
  }

  // Protected admin routes
  if (urlPath.startsWith('/admin/')) {
    const validToken = await middleware.verifyAdminAuth(headers);
    if (!validToken) {
      sendJson(res, 401, { error: 'Unauthorized. Please login at /admin' });
      return;
    }
  }

  // Admin API endpoints
  if (urlPath === '/admin/sessions' || urlPath === '/sessions/active') {
    await routes.admin.handleActiveSessions(req, res);
    return;
  }

  if (urlPath === '/admin/stats') {
    await routes.admin.handleAdminStats(req, res);
    return;
  }

  if (urlPath.startsWith('/admin/servers')) {
    await routes.admin.handleAdminServers(req, res, url);
    return;
  }

  if (urlPath === '/admin/search') {
    await routes.admin.handlePlayerSearch(req, res, url);
    return;
  }

  if (urlPath === '/admin/prerender-queue') {
    await routes.admin.handlePrerenderQueue(req, res);
    return;
  }

  // Profile lookup by UUID
  if (urlPath.startsWith('/profile/uuid/')) {
    const lookupUuid = urlPath.replace('/profile/uuid/', '');
    await routes.account.handleProfileLookupByUuid(req, res, lookupUuid, headers);
    return;
  }

  // Profile lookup by username
  if (urlPath.startsWith('/profile/username/')) {
    const lookupUsername = decodeURIComponent(urlPath.replace('/profile/username/', ''));
    await routes.account.handleProfileLookupByUsername(req, res, lookupUsername, headers);
    return;
  }

  // Profile endpoint
  if (urlPath.includes('/profile') || urlPath.includes('/user') || urlPath.includes('/me')) {
    routes.account.handleProfile(req, res, body, uuid, name);
    return;
  }

  // Cosmetics endpoint
  if (urlPath.includes('/cosmetic') || urlPath.includes('/unlocked') || urlPath.includes('/inventory')) {
    routes.account.handleCosmetics(req, res, body, uuid, name);
    return;
  }

  // Telemetry endpoint
  if (urlPath.includes('/telemetry') || urlPath.includes('/analytics') || urlPath.includes('/event')) {
    sendJson(res, 200, { success: true, received: true });
    return;
  }

  // Catch-all for unknown endpoints - important for research!
  console.log(`\x1b[31m[UNKNOWN ENDPOINT]\x1b[0m ${req.method} ${urlPath}`);
  const requestHost = req.headers.host;
  const authGrant = auth.generateAuthorizationGrant(uuid, name, crypto.randomUUID(), null, requestHost);
  const accessToken = auth.generateIdentityToken(uuid, name, null, ['game.base'], requestHost);
  sendJson(res, 200, {
    debug: true,
    message: 'Unknown endpoint captured for research',
    endpoint: urlPath,
    method: req.method,
    identityToken: accessToken,
    sessionToken: auth.generateSessionToken(uuid, requestHost),
    authorizationGrant: authGrant,
    accessToken: accessToken,
    tokenType: 'Bearer',
    user: { uuid, name, premium: true }
  });
}

main().catch(err => {
  console.error('Failed to start debug server:', err);
  process.exit(1);
});
