export const LIMIT_KINDS = [
  "wall_time",
  "cpu",
  "memory",
  "swap",
  "pids",
  "temp_storage",
  "output_size",
  "file_count",
] as const;

export type LimitKind = (typeof LIMIT_KINDS)[number];
export type UnixSignal = "SIGTERM" | "SIGKILL";

export interface IdentityPolicy {
  readonly runAsUser: number;
  readonly runAsGroup: number;
  readonly requireNonRoot: true;
}

export interface IsolationPolicy {
  readonly network: "none";
  readonly rootFilesystem: "read-only";
  /** Empty means every Linux capability is dropped. */
  readonly capabilities: readonly never[];
  readonly noNewPrivileges: true;
  readonly identity: IdentityPolicy;
}

export interface ResourceCeilings {
  /** Maximum aggregate CPU time used by the job cgroup. */
  readonly cpuTimeMs: number;
  readonly memoryBytes: number;
  readonly swapBytes: number;
  readonly pids: number;
  /** Maximum bytes in the writable per-job temporary filesystem. */
  readonly tempBytes: number;
  /** Maximum bytes retained as conversion output. */
  readonly outputBytes: number;
  /** Maximum regular files retained as conversion output. */
  readonly outputFiles: number;
  readonly wallTimeMs: number;
}

export interface CancellationPolicy {
  readonly scope: "cgroup";
  readonly initialSignal: "SIGTERM";
  readonly graceMs: number;
  readonly finalSignal: "SIGKILL";
}

export interface RunnerPolicy {
  readonly isolation: IsolationPolicy;
  readonly resources: ResourceCeilings;
  readonly cancellation: CancellationPolicy;
  readonly workDirectory: {
    readonly perJob: true;
    readonly cleanup: "every-terminal-state";
  };
}

export type TerminalState = "succeeded" | "failed" | "cancelled";

export type PublicFailureCode =
  | "RUNNER_CPU_LIMIT"
  | "RUNNER_MEMORY_LIMIT"
  | "RUNNER_SWAP_LIMIT"
  | "RUNNER_PID_LIMIT"
  | "RUNNER_TEMP_LIMIT"
  | "RUNNER_OUTPUT_SIZE_LIMIT"
  | "RUNNER_FILE_COUNT_LIMIT"
  | "RUNNER_TIMEOUT"
  | "RUNNER_CANCELLED"
  | "RUNNER_FAILED";

export interface LimitEvidence {
  readonly wallTimeExceeded?: boolean;
  readonly cpuTimeExceeded?: boolean;
  readonly memoryOom?: boolean;
  readonly swapExceeded?: boolean;
  readonly pidsExceeded?: boolean;
  readonly tempBytesExceeded?: boolean;
  readonly outputBytesExceeded?: boolean;
  readonly outputFilesExceeded?: boolean;
}

export interface ProcessOutcome {
  readonly cancellationRequested?: boolean;
  readonly exitCode?: number | null;
  readonly signal?: UnixSignal | null;
  readonly limits?: LimitEvidence;
}

export interface ClassifiedOutcome {
  readonly code: PublicFailureCode | "OK";
  readonly limit: LimitKind | null;
  readonly retryable: false;
}
