#!/usr/bin/env node
import {
  AuthManager,
  CollectorServer,
  HttpServer,
  PmStore,
  ProjectDiscovery,
  ProjectManager,
  Redactor,
  SessionManager,
  SqliteStore,
  isSqliteAvailable,
  migrateProjectIds,
  resolveTlsConfig
} from "./chunk-VNRQCY6B.js";
import {
  safeLog
} from "./chunk-CYDXIW4L.js";
import "./chunk-UP2VWCW5.js";

// src/standalone.ts
import { existsSync } from "fs";
import { join } from "path";
var HOST = process.env.RUNTIMESCOPE_HOST ?? "127.0.0.1";
var COLLECTOR_PORT = parseInt(process.env.RUNTIMESCOPE_PORT ?? "6767", 10);
var HTTP_PORT = parseInt(process.env.RUNTIMESCOPE_HTTP_PORT ?? "6768", 10);
var BUFFER_SIZE = parseInt(process.env.RUNTIMESCOPE_BUFFER_SIZE ?? "10000", 10);
var RETENTION_DAYS = parseInt(process.env.RUNTIMESCOPE_RETENTION_DAYS ?? "30", 10);
async function main() {
  try {
    const { fstatSync } = await import("fs");
    if (fstatSync(0).isSocket()) {
      process.stdin.on("end", () => process.exit(0));
      process.stdin.on("error", () => process.exit(0));
      process.stdin.resume();
    }
  } catch {
  }
  safeLog.error("[RuntimeScope] Starting standalone collector...");
  const projectManager = new ProjectManager();
  projectManager.ensureGlobalDir();
  const globalConfig = projectManager.getGlobalConfig();
  const envAuthToken = process.env.RUNTIMESCOPE_AUTH_TOKEN;
  const authFromEnv = envAuthToken ? {
    enabled: true,
    apiKeys: envAuthToken.split(",").map((t) => t.trim()).filter(Boolean).map((key, i) => ({
      key,
      label: `env-token-${i + 1}`,
      createdAt: Date.now()
    }))
  } : null;
  const authManager = new AuthManager({
    enabled: authFromEnv?.enabled ?? globalConfig.auth?.enabled ?? false,
    apiKeys: authFromEnv?.apiKeys ?? globalConfig.auth?.apiKeys ?? []
  });
  const tlsConfig = resolveTlsConfig() ?? globalConfig.tls ?? void 0;
  const redactor = new Redactor({
    enabled: globalConfig.redaction?.enabled ?? false,
    useBuiltIn: true,
    rules: globalConfig.redaction?.rules?.map((r) => ({
      name: r.name,
      pattern: new RegExp(r.pattern, "gi"),
      replacement: r.replacement
    }))
  });
  const corsOrigins = process.env.RUNTIMESCOPE_CORS_ORIGINS?.split(",").map((s) => s.trim()) ?? globalConfig.corsOrigins;
  if (authManager.isEnabled()) {
    const keyCount = authFromEnv?.apiKeys?.length ?? globalConfig.auth?.apiKeys?.length ?? 0;
    const source = authFromEnv ? "env" : "config";
    safeLog.error(`[RuntimeScope] Auth enabled (${keyCount} API key${keyCount === 1 ? "" : "s"} from ${source})`);
  }
  if (tlsConfig) {
    safeLog.error(`[RuntimeScope] TLS enabled (cert: ${tlsConfig.certPath})`);
  }
  if (redactor.isEnabled()) {
    safeLog.error("[RuntimeScope] Payload redaction enabled");
  }
  const collector = new CollectorServer({
    bufferSize: BUFFER_SIZE,
    projectManager,
    authManager,
    rateLimits: globalConfig.rateLimits,
    tls: tlsConfig
  });
  await collector.start({ port: COLLECTOR_PORT, host: HOST, maxRetries: 5, retryDelayMs: 1e3 });
  const store = collector.getStore();
  if (redactor.isEnabled()) {
    store.setRedactor(redactor);
  }
  const sqliteStores = collector.getSqliteStores();
  const sessionManager = new SessionManager(projectManager, sqliteStores, store);
  collector.onDisconnect((sessionId, projectName) => {
    try {
      sessionManager.createSnapshot(sessionId, projectName);
      safeLog.error(`[RuntimeScope] Session ${sessionId} metrics saved`);
    } catch {
    }
  });
  if (isSqliteAvailable()) {
    const cutoffMs = Date.now() - RETENTION_DAYS * 24 * 60 * 60 * 1e3;
    for (const projectName of projectManager.listProjects()) {
      const dbPath = projectManager.getProjectDbPath(projectName);
      if (existsSync(dbPath)) {
        try {
          const tempStore = new SqliteStore({ dbPath });
          const deleted = tempStore.deleteOldEvents(cutoffMs);
          if (deleted > 0) {
            safeLog.error(`[RuntimeScope] Pruned ${deleted} events older than ${RETENTION_DAYS}d from "${projectName}"`);
          }
          tempStore.close();
        } catch {
        }
      }
    }
  }
  let pmStore;
  let discovery;
  if (isSqliteAvailable()) {
    const pmDbPath = join(projectManager.rootDir, "pm.db");
    pmStore = new PmStore({ dbPath: pmDbPath });
    discovery = new ProjectDiscovery(pmStore, projectManager);
    collector.setPmStore(pmStore);
    discovery.discoverAll().then((result) => {
      safeLog.error(`[RuntimeScope] PM: ${result.projectsDiscovered} projects, ${result.sessionsDiscovered} sessions discovered`);
      projectManager.rebuildAppIndex(pmStore);
      try {
        const migrationResult = migrateProjectIds(projectManager, pmStore);
        if (migrationResult.unified > 0) {
          safeLog.error(`[RuntimeScope] Unified ${migrationResult.unified} project IDs`);
          for (const detail of migrationResult.details) {
            safeLog.error(`[RuntimeScope]   ${detail}`);
          }
          projectManager.rebuildAppIndex(pmStore);
        }
      } catch {
      }
    }).catch((err) => {
      safeLog.error("[RuntimeScope] PM discovery error:", err.message);
    });
  }
  const httpServer = new HttpServer(store, void 0, {
    authManager,
    allowedOrigins: corsOrigins,
    rateLimiter: collector.getRateLimiter(),
    pmStore,
    discovery,
    projectManager,
    getConnectedSessions: () => collector.getConnectedSessions(),
    isReady: () => collector.isReady(),
    createSnapshot: () => collector.createSnapshot(),
    renderMetrics: () => collector.getMetricsRegistry().render()
  });
  try {
    await httpServer.start({ port: HTTP_PORT, host: HOST, tls: tlsConfig });
  } catch (err) {
    safeLog.error("[RuntimeScope] HTTP API failed to start:", err.message);
  }
  collector.onConnect((sessionId, projectName, projectId) => {
    httpServer.broadcastSessionChange("session_connected", sessionId, projectName);
    if (pmStore) {
      try {
        pmStore.autoLinkApp(projectName, projectId);
      } catch {
      }
    }
  });
  collector.onDisconnect((sessionId, projectName) => {
    httpServer.broadcastSessionChange("session_disconnected", sessionId, projectName);
  });
  const proto = tlsConfig ? "wss" : "ws";
  const httpProto = tlsConfig ? "https" : "http";
  safeLog.error(`[RuntimeScope] Standalone collector ready`);
  safeLog.error(`[RuntimeScope]   WebSocket: ${proto}://${HOST}:${COLLECTOR_PORT}`);
  safeLog.error(`[RuntimeScope]   HTTP API:  ${httpProto}://${HOST}:${HTTP_PORT}`);
  safeLog.error(`[RuntimeScope]   Health:    ${httpProto}://${HOST}:${HTTP_PORT}/api/health`);
  safeLog.error(`[RuntimeScope]   Ingest:    POST ${httpProto}://${HOST}:${HTTP_PORT}/api/events`);
  let shuttingDown = false;
  const shutdown = async () => {
    if (shuttingDown) return;
    shuttingDown = true;
    safeLog.error("[RuntimeScope] Shutting down...");
    await httpServer.stop();
    collector.stop();
    pmStore?.close();
    process.exit(0);
  };
  process.on("SIGINT", () => {
    shutdown();
  });
  process.on("SIGTERM", () => {
    shutdown();
  });
}
main().catch((err) => {
  safeLog.error("[RuntimeScope] Fatal error:", err);
  process.exit(1);
});
//# sourceMappingURL=standalone.js.map