export type ConsumptionDimension =
  | "body-bytes"
  | "item-count"
  | "nesting-depth"
  | "decompressed-size"
  | "stream-duration"
  | "log-retention"
  | "retries"
  | "fan-out";

export type ConsumptionObservation = {
  dimension: ConsumptionDimension;
  declaredLimit: number;
  peakObserved: number;
  limitEnforcedDuringConsumption: boolean;
  rejectedAtConsumption: boolean;
  typedTerminalFailure?: {
    type: string;
    observed: boolean;
  };
};

export type ConsumptionLimitScenario = {
  scenarioId: string;
  kind: "consumption-limit";
  observations: ConsumptionObservation[];
};

export type WaitRetryLoopKind = "wait" | "retry";

export type TerminalLoopState = "completed" | "failed" | "busy" | "wedged" | "none";

export type WaitRetryObservation = {
  loopKind: WaitRetryLoopKind;
  boundedProgressRule?: string;
  maxAttempts?: number;
  maxWaitMs?: number;
  attemptsObserved: number;
  elapsedMs: number;
  cancellationPathAvailable: boolean;
  terminalState: TerminalLoopState;
  terminalFailureTyped: boolean;
  failureType?: string;
  statesDistinct: boolean;
};

export type WaitRetryScenario = {
  scenarioId: string;
  kind: "wait-retry";
  observation: WaitRetryObservation;
};

export type DeclaredProcessInheritance = {
  descriptors: number[];
  environmentKeys: string[];
  signals?: string[];
  workingDirectory: string;
  processGroup: string | number;
};

export type ObservedProcessInheritance = {
  descriptors: number[];
  environment: Record<string, string>;
  signals?: string[];
  workingDirectory: string;
  processGroup: string | number;
};

export type ChildProcessScenario = {
  scenarioId: string;
  kind: "child-process";
  declared: DeclaredProcessInheritance;
  observed: ObservedProcessInheritance;
};

export type ThresholdExceededObservation = {
  violationClass: "threshold-exceeded";
  resourceKind: string;
  observedValue: number;
  declaredThreshold: number;
  environmentContractConfirmed: boolean;
};

export type UnboundedGrowthObservation = {
  violationClass: "unbounded-growth";
  resourceKind: string;
  growthBounded: boolean;
};

export type IntegerOverflowObservation = {
  violationClass: "integer-overflow";
  resourceKind: string;
  observedValue: number;
  overflowDetected: boolean;
};

export type LeakedOwnershipObservation = {
  violationClass: "leaked-ownership";
  resourceKind: string;
  resourceIdentifier: string;
  ownerReleased: boolean;
};

export type BudgetThresholdObservation =
  | ThresholdExceededObservation
  | UnboundedGrowthObservation
  | IntegerOverflowObservation
  | LeakedOwnershipObservation;

export type BudgetThresholdScenario = {
  scenarioId: string;
  kind: "budget-threshold";
  observation: BudgetThresholdObservation;
};

export type BoundedScenario =
  | ConsumptionLimitScenario
  | WaitRetryScenario
  | ChildProcessScenario
  | BudgetThresholdScenario;

export type BoundedFixture = {
  fixtureId: string;
  boundedVersion: string;
  scenarios: BoundedScenario[];
  intentionalException?: {
    rules: string[];
    reason: string;
  };
};
