import { GraphType } from './graph.js';

/**
 * Graph snapshot — read-only view of the multi-graph memory adjacency
 * (issue #691 PR 2/5).
 *
 * Composes the JSONL edge store from `graph.ts` with optional node-metadata
 * loading so HTTP / MCP / future CLI surfaces can return a consistent
 * `{ nodes, edges, generatedAt }` shape suitable for the admin pane scaffold
 * shipped in PR 1/5.
 *
 * All inputs are validated and clamped at this layer so the access surface
 * (which is responsible for HTTP/MCP-flavored errors) can keep the wiring
 * thin.  The module is pure async I/O — no global state, no caches.
 */

/** Default `limit` when the caller omits it. */
declare const GRAPH_SNAPSHOT_DEFAULT_LIMIT = 500;
/** Hard upper bound on `limit` to keep responses sized for the admin pane. */
declare const GRAPH_SNAPSHOT_MAX_LIMIT = 5000;
/** Categories accepted by the `categories` filter; matches `MemoryFile.frontmatter.category`. */
type GraphSnapshotCategory = string;
interface GraphSnapshotNode {
    /** Stable identifier — relative memory path (matches `GraphEdge.from` / `to`). */
    id: string;
    /** Short human label.  Falls back to the basename when no metadata is available. */
    label: string;
    /** Memory category (e.g. `fact`, `decision`, `entity`).  `"unknown"` when metadata is missing. */
    kind: string;
    /** Aggregate edge confidence touching this node, used for sizing in the admin pane. */
    score: number;
    /** Most recent edge timestamp (ISO) touching this node — best-effort recency signal. */
    lastUpdated: string | null;
}
interface GraphSnapshotEdge {
    source: string;
    target: string;
    kind: GraphType;
    /** Edge confidence in [0, 1]; legacy edges without confidence return 1.0. */
    confidence: number;
}
interface GraphSnapshotResponse {
    nodes: GraphSnapshotNode[];
    edges: GraphSnapshotEdge[];
    generatedAt: string;
}
interface GraphSnapshotRequest {
    /** Max number of edges to include (after filtering).  Default 500, max 5000. */
    limit?: number;
    /** Inclusive lower bound on edge `ts` (ISO string).  Edges older than this are dropped. */
    since?: string;
    /** When set, restrict the snapshot to the focus node and its direct neighbors. */
    focusNodeId?: string;
    /**
     * Optional category allow-list.  Edges are kept only when both endpoints
     * resolve to nodes whose category falls in this set; nodes are kept only
     * when their category matches.  When omitted, no category filter is applied.
     */
    categories?: GraphSnapshotCategory[];
}
/**
 * Loader contract: given a relative memory path, return `{ category, label,
 * updated }` or `null` when the memory cannot be resolved.  Implementations
 * typically wrap `StorageManager.readMemoryByPath`; the snapshot module stays
 * agnostic so tests can pass a synchronous in-memory map.
 */
type GraphSnapshotNodeLoader = (relPath: string) => Promise<GraphSnapshotNodeMetadata | null>;
interface GraphSnapshotNodeMetadata {
    /** Memory category, e.g. `fact` / `decision` / `entity`. */
    category: string;
    /** Display label — usually the memory id or the entity name. */
    label: string;
    /** ISO `updated` timestamp from frontmatter, when available. */
    updated?: string;
}
/**
 * Coerce a caller-supplied limit into the `[1, GRAPH_SNAPSHOT_MAX_LIMIT]` range.
 *
 * - `undefined` / `null` → `GRAPH_SNAPSHOT_DEFAULT_LIMIT`.
 * - non-finite or non-integer → throws `Error` (callers translate to 400).
 * - `<= 0` → throws.
 * - `> GRAPH_SNAPSHOT_MAX_LIMIT` → clamped to the max (no error — admin
 *   panel callers send liberal limits).
 */
declare function normalizeGraphSnapshotLimit(raw: unknown): number;
/**
 * Validate and parse an ISO timestamp into a millisecond epoch.  Throws
 * when the input cannot be parsed; callers translate to a 400.  `undefined`
 * input yields `undefined`.
 */
declare function parseGraphSnapshotSince(raw: string | undefined): number | undefined;
/**
 * Build a `GraphSnapshotResponse` from the raw edge JSONL on disk plus an
 * optional node-metadata loader.
 *
 * The function is split into pure subroutines so HTTP / MCP / tests can
 * exercise the same logic without spinning up a full `StorageManager`.
 */
declare function buildGraphSnapshot(opts: {
    memoryDir: string;
    graphConfig: {
        entityGraphEnabled: boolean;
        timeGraphEnabled: boolean;
        causalGraphEnabled: boolean;
    };
    request: GraphSnapshotRequest;
    loadNode: GraphSnapshotNodeLoader;
    /** Override clock for deterministic tests. */
    now?: () => Date;
}): Promise<GraphSnapshotResponse>;

export { GRAPH_SNAPSHOT_DEFAULT_LIMIT, GRAPH_SNAPSHOT_MAX_LIMIT, type GraphSnapshotCategory, type GraphSnapshotEdge, type GraphSnapshotNode, type GraphSnapshotNodeLoader, type GraphSnapshotNodeMetadata, type GraphSnapshotRequest, type GraphSnapshotResponse, buildGraphSnapshot, normalizeGraphSnapshotLimit, parseGraphSnapshotSince };
