export type LeakageKind =
  | "shared-state"
  | "real-home-directory"
  | "stale-process"
  | "cache"
  | "port"
  | "database-row"
  | "clock"
  | "random-source"
  | "artifact";

export type ScenarioExecutionResult = {
  scenarioId: string;
  identity: string;
  result: unknown;
};

export type ExecutionOrdering = {
  orderingId: string;
  sequence: string[];
  observedResults: ScenarioExecutionResult[];
};

export type RepetitionRun = {
  repetitionId: string;
  runCount: number;
  observedResults: ScenarioExecutionResult[];
};

export type ParallelExecution = {
  parallelId: string;
  contexts: Array<{
    contextId: string;
    scenarioId: string;
    identity: string;
    result: unknown;
  }>;
};

export type ResourceLeak = {
  kind: LeakageKind;
  leakedFromContext: string;
  observedInContext: string;
  detail: string;
};

export type MetamorphicExecutionScenario = {
  scenarioId: string;
  kind: "metamorphic-execution";
  baseline: ScenarioExecutionResult;
  constraints: {
    orderInvariant: boolean;
    repetitionInvariant: boolean;
    parallelIndependent: boolean;
    stableIdentity: boolean;
  };
  orderings: ExecutionOrdering[];
  repetitions: RepetitionRun[];
  parallelRuns?: ParallelExecution[];
  leakedResources?: ResourceLeak[];
};

export type DeclaredIsolationMode = "demo" | "preview" | "fixture" | "offline";

export type DependencyClassification = "live" | "mock" | "local-fixture" | "production";

export type DependencyAccessAttempt = {
  target: string;
  classification: DependencyClassification;
  reached: boolean;
  channel?: string;
};

export type ModeIsolationScenario = {
  scenarioId: string;
  kind: "mode-isolation";
  mode: DeclaredIsolationMode;
  isolationContract: {
    declaresIsolation: boolean;
    allowedDependencyTargets: string[];
  };
  accessAttempts: DependencyAccessAttempt[];
};

export type IsolationScenario = MetamorphicExecutionScenario | ModeIsolationScenario;

export type IsolationFixture = {
  fixtureId: string;
  isolationVersion: string;
  scenarios: IsolationScenario[];
  intentionalException?: {
    rules: string[];
    reason: string;
  };
};
