export type FilesystemPlatform = "linux" | "darwin" | "win32";

export type PathContainmentScenario = {
  scenarioId: string;
  kind: "path-containment";
  platform: FilesystemPlatform;
  declaredRoot: string;
  operationPath: string;
  resolvedPath: string;
  canonicalContainmentChecked: boolean;
  containedAfterResolution: boolean;
  traversalRejected: boolean;
  rootUnambiguous: boolean;
  platformSemanticsPreserved: boolean;
};

export type ReplaceStrategy =
  | "atomic-rename"
  | "in-place-write"
  | "truncate-write"
  | "copy-then-rename"
  | "transactional";

export type AtomicReplacementScenario = {
  scenarioId: string;
  kind: "atomic-replacement";
  targetPath: string;
  readersRequireWholeFileConsistency: boolean;
  replaceStrategy: ReplaceStrategy;
  atomicOrTransactional: boolean;
  partialCanonicalStateObserved: boolean;
};

export type ArtifactKind = "temp" | "lock";

export type StaleOwnerRecovery = {
  contractDeclared: boolean;
  staleDetected: boolean;
  recovered: boolean;
  recoveryMethod?: string;
};

export type ArtifactOwnershipScenario = {
  scenarioId: string;
  kind: "artifact-ownership";
  artifactKind: ArtifactKind;
  path: string;
  ownerId: string;
  collisionSafe: boolean;
  boundedLifetime: boolean;
  maxLifetimeMs?: number;
  observedLifetimeMs?: number;
  cleanupOnExit: boolean;
  cleanupObserved: boolean;
  staleOwnerRecovery: StaleOwnerRecovery;
};

export type FilesystemScenario =
  | PathContainmentScenario
  | AtomicReplacementScenario
  | ArtifactOwnershipScenario;

export type FilesystemFixture = {
  fixtureId: string;
  filesystemVersion: string;
  scenarios: FilesystemScenario[];
  intentionalException?: {
    rules: string[];
    reason: string;
  };
};
