import type { StructuredJsonlLogger } from "./structured-log.js";

export class WorkerAiCallGate {
  private readonly getStorageStatus: () => "active" | "full" | "unavailable";
  private readonly logger: StructuredJsonlLogger;

  constructor(input: {
    getStorageStatus: () => "active" | "full" | "unavailable";
    logger: StructuredJsonlLogger;
  }) {
    this.getStorageStatus = input.getStorageStatus;
    this.logger = input.logger;
  }

  async execute<T>(correlationId: string, objectId: string, externalCall: () => Promise<T>) {
    const initialStatus = this.getStorageStatus();
    if (initialStatus === "full") return { reason: "storage_full" as const, status: "blocked" as const };
    if (initialStatus === "unavailable") return { reason: "storage_unavailable" as const, status: "blocked" as const };
    try {
      this.logger.write({
        correlation_id: correlationId,
        error_category: "none",
        object_id: objectId,
        status_category: "starting",
      });
    } catch {
      return { reason: "storage_unavailable" as const, status: "blocked" as const };
    }
    const statusAfterLog = this.getStorageStatus();
    if (statusAfterLog === "full") return { reason: "storage_full" as const, status: "blocked" as const };
    if (statusAfterLog === "unavailable") return { reason: "storage_unavailable" as const, status: "blocked" as const };
    const started = Date.now();
    const value = await externalCall();
    try {
      this.logger.write({
        correlation_id: correlationId,
        duration_ms: Date.now() - started,
        error_category: "none",
        object_id: objectId,
        status_category: "completed",
      });
    } catch {
      // The completed call cannot be undone; the write failure blocks every later call.
    }
    return { status: "completed" as const, value };
  }
}
