export const pipelineProvenanceAnnotationKeys = {
  configRef: "unidesk.ai/owning-config-ref",
  effectiveConfigSha256: "unidesk.ai/effective-config-sha256",
  renderer: "unidesk.ai/source-artifact-renderer",
  mode: "unidesk.ai/source-artifact-mode",
} as const;

export interface PipelineProvenanceContract {
  readonly configRef: string;
  readonly effectiveConfigSha256: string;
  readonly renderer: string;
  readonly mode: string;
}

export function pipelineProvenanceAnnotations(provenance: PipelineProvenanceContract): Record<string, string> {
  return {
    [pipelineProvenanceAnnotationKeys.configRef]: provenance.configRef,
    [pipelineProvenanceAnnotationKeys.effectiveConfigSha256]: provenance.effectiveConfigSha256,
    [pipelineProvenanceAnnotationKeys.renderer]: provenance.renderer,
    [pipelineProvenanceAnnotationKeys.mode]: provenance.mode,
  };
}

export function withPipelineProvenanceAnnotations(
  manifest: Record<string, unknown>,
  provenance: PipelineProvenanceContract,
): Record<string, unknown> {
  const next = structuredClone(manifest);
  const metadata = asRecord(next.metadata, "manifest.metadata");
  const annotations = metadata.annotations === undefined ? {} : asRecord(metadata.annotations, "manifest.metadata.annotations");
  metadata.annotations = { ...annotations, ...pipelineProvenanceAnnotations(provenance) };
  return next;
}

export function pipelineProvenanceFromManifest(manifest: Record<string, unknown>): PipelineProvenanceContract | null {
  const metadata = isRecord(manifest.metadata) ? manifest.metadata : {};
  const annotations = isRecord(metadata.annotations) ? metadata.annotations : {};
  const configRef = annotations[pipelineProvenanceAnnotationKeys.configRef];
  const effectiveConfigSha256 = annotations[pipelineProvenanceAnnotationKeys.effectiveConfigSha256];
  const renderer = annotations[pipelineProvenanceAnnotationKeys.renderer];
  const mode = annotations[pipelineProvenanceAnnotationKeys.mode];
  if ([configRef, effectiveConfigSha256, renderer, mode].some((value) => typeof value !== "string" || value.length === 0)) return null;
  return { configRef, effectiveConfigSha256, renderer, mode } as PipelineProvenanceContract;
}

function asRecord(value: unknown, path: string): Record<string, unknown> {
  if (!isRecord(value)) throw new Error(`${path} must be an object`);
  return value;
}

function isRecord(value: unknown): value is Record<string, unknown> {
  return value !== null && typeof value === "object" && !Array.isArray(value);
}
