import { DockerSandbox } from './docker.js';
import type { SandboxConfig } from '../config/schema.js';

/**
 * Manages per-session Docker sandboxes.
 * Creates containers lazily on first access, destroys on session cleanup.
 */
export class SandboxManager {
  private sandboxes = new Map<string, DockerSandbox>();
  private config: SandboxConfig;

  constructor(config: SandboxConfig) {
    this.config = config;
  }

  /** Get or create a sandbox for a session. */
  async getOrCreate(sessionId: string): Promise<DockerSandbox> {
    let sandbox = this.sandboxes.get(sessionId);
    if (sandbox) {return sandbox;}

    sandbox = new DockerSandbox({
      sessionId,
      image: this.config.image,
      workspaceDir: this.config.workspace_dir,
      network: this.config.network,
      memoryLimit: this.config.memory_limit,
      cpuLimit: this.config.cpu_limit,
      timeoutSeconds: this.config.timeout_seconds,
    });

    await sandbox.create();
    this.sandboxes.set(sessionId, sandbox);
    return sandbox;
  }

  /** Destroy a specific session's sandbox. */
  async destroy(sessionId: string): Promise<void> {
    const sandbox = this.sandboxes.get(sessionId);
    if (!sandbox) {return;}

    await sandbox.destroy();
    this.sandboxes.delete(sessionId);
  }

  /** Destroy all sandboxes (daemon shutdown). */
  async destroyAll(): Promise<void> {
    const entries = Array.from(this.sandboxes.entries());
    await Promise.allSettled(
      entries.map(async ([_id, sandbox]) => {
        await sandbox.destroy();
      }),
    );
    this.sandboxes.clear();
  }
}
