/**
 * Port: Where documentation context comes from.
 *
 * Adapters:
 * - SanityDocFetcher — GROQ queries against Sanity Content Lake
 *   (perspective diffing, document overlays, URL fetching)
 * - InMemoryDocFetcher (testing) — returns pre-loaded content
 *
 * The pipeline orchestrator and all downstream steps work with
 * FetchResult regardless of where the documentation came from.
 */
import type { GeneralizedTaskDefinition } from "../types/generalized-task.js";
/**
 * A fetched documentation context ready for injection into prompts.
 *
 * Each DocContext corresponds to one task's documentation — the combined
 * markdown of all canonical docs for that task plus any overlays/URLs.
 */
export interface DocContext {
    /** The task ID this context belongs to */
    taskId: string;
    /** Combined markdown content of the fetched documentation */
    content: string;
    /** Document slugs included in this context */
    slugs: string[];
    /** Approximate token count (length / 4) */
    tokenCount?: number;
}
/**
 * Configuration for a documentation source.
 *
 * Maps to the resolved source config from config/sources.yaml, but
 * expressed as a domain type independent of the YAML structure.
 */
export interface DocSourceConfig {
    /** Base URL (e.g., "https://www.sanity.io/docs") */
    baseUrl?: string;
    /** Sanity dataset (e.g., "production") */
    dataset?: string;
    /** Sanity project ID */
    projectId?: string;
    /** Custom headers for authenticated requests */
    headers?: Record<string, string>;
    /** Content release perspective (e.g., bundle name) */
    perspective?: string;
    /** Direct URLs to fetch and include in context */
    urls?: string[];
    /** Sanity document IDs for overlay (replace/append to canonical docs) */
    documentIds?: string[];
}
/** Metadata about a fetched document, for traceability */
export interface DocumentManifestEntry {
    _id: string;
    _rev: string;
    slug: string;
    /** Parent section slug (`primarySection->slug.current`), when resolvable. */
    sectionSlug?: string;
    /**
     * Full URL path under `/docs/` (e.g. `content-lake/groq-introduction`)
     * composed via `buildContextDocPath` from `sectionSlug + "/" + slug`.
     * Optional — historical manifests written before W0287 only carry
     * `slug`; downstream `DocumentRef` builders fall back to slug-only
     * display when this is absent.
     */
    path?: string;
    title: string;
}
/** Impact of a content release on canonical documents */
export interface ReleaseImpact {
    added: string[];
    modified: string[];
    removed: string[];
    unchanged: string[];
}
/** Summary of document overlay operations */
export interface DocumentOverlaySummary {
    appendedCount: number;
    documentIds: string[];
    replacedSlugs: string[];
}
/** Metadata for a single URL fetch result */
export interface UrlFetchEntry {
    contentLength?: number;
    error?: string;
    method: string;
    status?: number;
    url: string;
}
/** Summary of URL fetch operations */
export interface UrlFetchSummary {
    failures: {
        error?: string;
        url: string;
    }[];
    fetchedUrls: UrlFetchEntry[];
    totalFailed: number;
    totalFetched: number;
}
/**
 * Per-task entry in the symbol-reference index manifest (W0197).
 *
 * One entry is emitted per task that the fetcher processed, regardless of
 * whether extraction yielded any symbols. The grader-context consumer
 * uses `symbolCount > 0` to decide between symbol-index and full-doc
 * injection — distinguishing "extraction ran and produced nothing"
 * (entry present, count zero — observable fallback) from "fetcher hadn't
 * run with W0197" (no entry — silent fallback).
 */
export interface SymbolIndexManifestEntry {
    taskId: string;
    /** Repo-relative path to the per-task index artifact. */
    path: string;
    /** Total deduped symbols in the index (post-merge). */
    symbolCount: number;
    /** Per-tier breakdown for observability. */
    tierBreakdown: {
        typeDef: number;
        heading: number;
        inlineCode: number;
        codeBlock: number;
    };
}
/** Metadata about the fetch operation, for downstream pipeline consumption */
export interface FetchMetadata {
    /** Document manifest for traceability (slug, _id, _rev, title) */
    manifest?: DocumentManifestEntry[];
    /** Release impact from perspective diffing */
    releaseImpact?: ReleaseImpact;
    /** Document overlay operations summary */
    documentOverlay?: DocumentOverlaySummary;
    /** URL fetch operations summary */
    urlFetch?: UrlFetchSummary;
    /**
     * Per-task symbol-index manifest (W0197). Always populated when the
     * fetcher emits per-task index artifacts; the in-memory copy mirrors
     * the on-disk `contexts/canonical-symbols/manifest.json`.
     */
    symbolIndexes?: SymbolIndexManifestEntry[];
}
/** Complete result of a doc fetch operation */
export interface FetchResult {
    /** Per-task documentation contexts */
    contexts: DocContext[];
    /** Optional metadata about the fetch (manifests, impact, overlays, URLs) */
    metadata?: FetchMetadata;
}
/**
 * Port: Where documentation context comes from.
 *
 * The pipeline never knows HOW docs are fetched — it only sees
 * FetchResult. The adapter handles GROQ queries, Portable Text
 * conversion, URL fetching, perspective diffing, document overlays, etc.
 */
export interface DocFetcher {
    /**
     * Fetch documentation context for a set of tasks.
     *
     * The adapter:
     * 1. Collects unique slugs from tasks' canonicalDocs
     * 2. Fetches documents from the source (with perspective/overlay support)
     * 3. Converts to markdown
     * 4. Assembles per-task context (combining all canonical docs + overlays)
     * 5. Writes context files to disk (for Promptfoo consumption)
     * 6. Returns structured metadata (manifest, release impact, etc.)
     *
     * @param tasks — Task definitions with canonical doc references
     * @param source — Where to fetch documentation from
     * @returns Fetched doc contexts + optional metadata
     */
    fetch(tasks: GeneralizedTaskDefinition[], source?: DocSourceConfig): Promise<FetchResult>;
}
