import { z } from 'zod';

/**
 * Logger interface for consistent logging across the application
 * Simplified version without Winston dependency
 */
/**
 * Log levels
 */
declare enum LogLevel {
    SILLY = 0,
    VERBOSE = 1,
    DEBUG = 2,
    INFO = 3,
    WARN = 4,
    ERROR = 5,
    NONE = 6
}
/**
 * Logger implementation with Component Interface Standardization pattern
 */
type LogFormat = "text" | "json";
interface LoggerOptions {
    level?: LogLevel;
    context?: string;
    useStderr?: boolean;
    format?: LogFormat;
    /** Path to a log file. Always writes JSON, one line per entry. */
    logFile?: string;
}
declare class Logger {
    /** The singleton instance */
    private static instance;
    private level;
    private context;
    private useStderr;
    private format;
    private logFile;
    private fileHandle;
    /**
     * Private constructor to enforce singleton pattern
     */
    private constructor();
    /**
     * Get the singleton instance of Logger
     */
    static getInstance(options?: LoggerOptions): Logger;
    /**
     * Reset the singleton instance (primarily for testing)
     */
    static resetInstance(): void;
    /**
     * Create a fresh instance without affecting the singleton
     */
    static createFresh(options?: LoggerOptions): Logger;
    /**
     * Format a log entry for output.
     * Text: [timestamp] [context] message
     * JSON: {"ts":"...","level":"...","ctx":"...","msg":"...","data":[...]}
     */
    private formatEntry;
    /**
     * Log a message at the 'silly' level
     */
    /**
     * Write a formatted log entry to the appropriate output stream.
     * JSON format: single string argument (no spread).
     * Text format: message + spread args for console formatting.
     */
    private write;
    /**
     * Format a JSON log entry (used for file output regardless of console format).
     */
    private formatJsonEntry;
    silly(message: string, ...args: unknown[]): void;
    verbose(message: string, ...args: unknown[]): void;
    debug(message: string, ...args: unknown[]): void;
    info(message: string, ...args: unknown[]): void;
    warn(message: string, ...args: unknown[]): void;
    error(message: string, ...args: unknown[]): void;
    /**
     * Create a child logger with a specific context
     */
    child(context: string): Logger;
    /**
     * Configure the logger to use stderr for all output
     * Useful for MCP servers that need stdout for JSON-RPC
     */
    setUseStderr(useStderr: boolean): void;
}

/**
 * Context passed to all DataSource operations
 * Contains internal state that should not be mixed with user query parameters
 */
interface BaseDataSourceContext {
    /**
     * Whether to filter to only published/complete content
     * Set by site-builder: true for production, false for preview
     */
    publishedOnly?: boolean;
    /**
     * Scoped entity service that auto-applies publishedOnly filter
     * Datasources should use this instead of their injected entityService
     * to ensure consistent filtering behavior across environments
     */
    entityService: EntityService;
}
/**
 * DataSource Interface
 *
 * Provides data for templates through fetch, generate, or transform operations.
 * DataSources are registered in the DataSourceRegistry and referenced by templates
 * via their dataSourceId property.
 */
interface DataSource {
    /**
     * Unique identifier for this data source
     */
    id: string;
    /**
     * Human-readable name for this data source
     */
    name: string;
    /**
     * Optional description of what this data source provides
     */
    description?: string;
    /**
     * Optional: Fetch existing data
     * Used by data sources that aggregate or retrieve data (e.g., dashboard stats, API data)
     * DataSources validate output using the provided schema
     * @param query - Query parameters for fetching data
     * @param outputSchema - Schema for validating output data
     * @param context - Context with environment
     */
    fetch?: <T>(query: unknown, outputSchema: z.ZodSchema<T>, context: BaseDataSourceContext) => Promise<T>;
    /**
     * Optional: Generate new content
     * Used by data sources that create content (e.g., AI-generated content, reports)
     */
    generate?: <T>(request: unknown, schema: z.ZodSchema<T>) => Promise<T>;
    /**
     * Optional: Transform content between formats
     * Used by data sources that convert content (e.g., markdown to HTML, data formatting)
     */
    transform?: <T>(content: unknown, format: string, schema: z.ZodSchema<T>) => Promise<T>;
}

declare const canonicalContentVisibilitySchema: z.ZodEnum<["public", "shared", "restricted"]>;
type ContentVisibility = z.infer<typeof canonicalContentVisibilitySchema>;
type RawContentVisibility = ContentVisibility | "private";

/**
 * Options for entity mutation operations (create, update, upsert)
 */
interface EntityJobOptions {
    priority?: number;
    maxRetries?: number;
}

/**
 * Options for entity creation (extends EntityJobOptions with deduplication)
 */
interface CreateEntityOptions extends EntityJobOptions {
    deduplicateId?: boolean;
}
/**
 * Result of an entity mutation that triggers an embedding job.
 * When skipped is true, content was unchanged — no DB write, no event, no embedding job.
 */
interface EntityMutationResult {
    entityId: string;
    jobId: string;
    skipped: boolean;
}
/**
 * Input for adapter-validated direct creation from finalized markdown.
 */
interface CreateEntityFromMarkdownInput {
    entityType: string;
    id: string;
    markdown: string;
}
/**
 * Data for storing an embedding for an entity
 */
interface StoreEmbeddingData {
    entityId: string;
    entityType: string;
    embedding: Float32Array;
    contentHash: string;
}
/**
 * Base entity type - generic to support typed metadata
 * TMetadata defaults to Record<string, unknown> for backward compatibility
 */
interface BaseEntity<TMetadata = Record<string, unknown>> {
    id: string;
    entityType: string;
    content: string;
    created: string;
    updated: string;
    visibility: ContentVisibility;
    metadata: TMetadata;
    /** SHA256 hash of content for change detection */
    contentHash: string;
}
/**
 * Entity input type for creation - allows partial entities with optional system fields
 * contentHash is excluded because it's computed automatically by the entity service
 */
type EntityInput<T extends BaseEntity> = Omit<T, "id" | "created" | "updated" | "contentHash" | "visibility"> & {
    id?: string;
    created?: string;
    updated?: string;
    visibility?: RawContentVisibility;
};
/**
 * Search result type
 */
interface SearchResult<T extends BaseEntity = BaseEntity> {
    entity: T;
    score: number;
    excerpt: string;
}
/**
 * Sort field specification for multi-field sorting
 */
interface SortField {
    /** Field to sort by - "created", "updated", or a metadata field name */
    field: string;
    /** Sort direction */
    direction: "asc" | "desc";
    /** Sort NULL values before non-NULL values (default: false / SQLite default) */
    nullsFirst?: boolean;
}
/**
 * List entities options
 * Generic over metadata type for type-safe filtering
 */
interface ListOptions<TMetadata = Record<string, unknown>> {
    limit?: number;
    offset?: number;
    /** Multi-field sorting - supports system fields (created, updated) and metadata fields */
    sortFields?: SortField[];
    filter?: {
        metadata?: Partial<TMetadata>;
        visibilityScope?: ContentVisibility;
    };
    /** Filter to only entities with metadata.status = "published" */
    publishedOnly?: boolean;
}
/**
 * Search options
 */
interface SearchOptions {
    limit?: number;
    offset?: number;
    types?: string[];
    excludeTypes?: string[];
    sortBy?: "relevance" | "created" | "updated";
    sortDirection?: "asc" | "desc";
    /** Score multipliers per entity type - applied after initial search */
    weight?: Record<string, number>;
    visibilityScope?: ContentVisibility;
    /** Include queued/failed generation stubs in search results (default: false) */
    includeUngenerated?: boolean;
}
/**
 * Configuration for entity type registration
 */
interface EntityTypeConfig {
    /** Score multiplier for search results (default: 1.0) */
    weight?: number;
    /** Whether to generate embeddings for this entity type (default: true).
     *  Set to false for entity types with non-textual content (e.g., images). */
    embeddable?: boolean;
    /** Whether this entity type may be used as source material for derived projections (default: true).
     *  Set to false for projection outputs that would create feedback loops. */
    projectionSource?: boolean;
    /** Publish semantics for status-bearing entity types. Statuses listed here
     *  represent publication commitment/execution states and require the
     *  `publish` entity action when entered or modified. */
    publish?: {
        publishStatuses: string[];
    };
}
/**
 * Core entity service interface for read-only operations
 * Used by core plugins that need entity access but shouldn't modify entities
 */
interface GetEntityRequest {
    entityType: string;
    id: string;
    /**
     * Optional visibility scope. Undefined fails closed to "public" — callers
     * with elevated access must opt up explicitly.
     */
    visibilityScope?: ContentVisibility;
}
type GetEntityRawRequest = GetEntityRequest;
interface ListEntitiesRequest {
    entityType: string;
    options?: ListOptions | undefined;
}
interface CountEntitiesRequest {
    entityType: string;
    options?: Pick<ListOptions, "publishedOnly" | "filter"> | undefined;
}
interface CreateEntityRequest<T extends BaseEntity> {
    entity: EntityInput<T>;
    options?: CreateEntityOptions | undefined;
}
interface CreateEntityFromMarkdownRequest {
    input: CreateEntityFromMarkdownInput;
    options?: CreateEntityOptions | undefined;
}
interface UpdateEntityRequest<T extends BaseEntity> {
    entity: T;
    options?: EntityJobOptions | undefined;
}
interface DeleteEntityRequest {
    entityType: string;
    id: string;
}
interface UpsertEntityRequest<T extends BaseEntity> {
    entity: T;
    options?: EntityJobOptions | undefined;
}
interface EntitySearchRequest {
    query: string;
    options?: SearchOptions | undefined;
}
interface SearchWithDistancesRequest {
    query: string;
}
interface ICoreEntityService {
    getEntity<T extends BaseEntity>(request: GetEntityRequest): Promise<T | null>;
    /**
     * Get entity without content resolution (raw)
     * Used internally to avoid recursion when resolving image references
     */
    getEntityRaw<T extends BaseEntity>(request: GetEntityRawRequest): Promise<T | null>;
    listEntities<T extends BaseEntity>(request: ListEntitiesRequest): Promise<T[]>;
    search<T extends BaseEntity = BaseEntity>(request: EntitySearchRequest): Promise<SearchResult<T>[]>;
    getEntityTypes(): string[];
    hasEntityType(type: string): boolean;
    countEntities(request: CountEntitiesRequest): Promise<number>;
    /**
     * Group counts by entity type. Fails closed: undefined visibilityScope
     * filters to public-only counts so aggregate insights cannot reveal
     * non-public entity existence.
     */
    getEntityCounts(visibilityScope?: ContentVisibility): Promise<Array<{
        entityType: string;
        count: number;
    }>>;
    /** Get configuration for a specific entity type */
    getEntityTypeConfig(type: string): EntityTypeConfig;
    /** Get weight map for all registered entity types with non-default weights */
    getWeightMap(): Record<string, number>;
}
interface EntityService extends ICoreEntityService {
    createEntity<T extends BaseEntity>(request: CreateEntityRequest<T>): Promise<EntityMutationResult>;
    createEntityFromMarkdown(request: CreateEntityFromMarkdownRequest): Promise<EntityMutationResult>;
    updateEntity<T extends BaseEntity>(request: UpdateEntityRequest<T>): Promise<EntityMutationResult>;
    deleteEntity(request: DeleteEntityRequest): Promise<boolean>;
    upsertEntity<T extends BaseEntity>(request: UpsertEntityRequest<T>): Promise<EntityMutationResult & {
        created: boolean;
    }>;
    storeEmbedding(data: StoreEmbeddingData): Promise<void>;
    serializeEntity(entity: BaseEntity): string;
    deserializeEntity(markdown: string, entityType: string): Partial<BaseEntity>;
    countEmbeddings(): Promise<number>;
    searchWithDistances(request: SearchWithDistancesRequest): Promise<Array<{
        entityId: string;
        entityType: string;
        distance: number;
    }>>;
    initialize(): Promise<void>;
    getAsyncJobStatus(jobId: string): Promise<{
        status: "pending" | "processing" | "completed" | "failed";
        error?: string;
    } | null>;
}

/**
 * Schema for pagination information
 * Used by datasources that return paginated lists
 */
declare const paginationInfoSchema: z.ZodObject<{
    currentPage: z.ZodNumber;
    totalPages: z.ZodNumber;
    totalItems: z.ZodNumber;
    pageSize: z.ZodNumber;
    hasNextPage: z.ZodBoolean;
    hasPrevPage: z.ZodBoolean;
}, "strip", z.ZodTypeAny, {
    currentPage: number;
    totalPages: number;
    totalItems: number;
    pageSize: number;
    hasNextPage: boolean;
    hasPrevPage: boolean;
}, {
    currentPage: number;
    totalPages: number;
    totalItems: number;
    pageSize: number;
    hasNextPage: boolean;
    hasPrevPage: boolean;
}>;
/**
 * Pagination information type
 */
type PaginationInfo = z.infer<typeof paginationInfoSchema>;

/**
 * Zod schema for the base query fields.
 * Subclasses can extend this with `.extend()` for additional fields.
 */
declare const baseQuerySchema: z.ZodObject<{
    id: z.ZodOptional<z.ZodString>;
    limit: z.ZodOptional<z.ZodNumber>;
    page: z.ZodOptional<z.ZodNumber>;
    pageSize: z.ZodOptional<z.ZodNumber>;
    baseUrl: z.ZodOptional<z.ZodString>;
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
    id: z.ZodOptional<z.ZodString>;
    limit: z.ZodOptional<z.ZodNumber>;
    page: z.ZodOptional<z.ZodNumber>;
    pageSize: z.ZodOptional<z.ZodNumber>;
    baseUrl: z.ZodOptional<z.ZodString>;
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
    id: z.ZodOptional<z.ZodString>;
    limit: z.ZodOptional<z.ZodNumber>;
    page: z.ZodOptional<z.ZodNumber>;
    pageSize: z.ZodOptional<z.ZodNumber>;
    baseUrl: z.ZodOptional<z.ZodString>;
}, z.ZodTypeAny, "passthrough">>;
/**
 * Zod schema for the outer datasource input (entityType + query).
 * Subclasses can extend the inner query via `baseQuerySchema.extend()`.
 */
declare const baseInputSchema: z.ZodObject<{
    entityType: z.ZodOptional<z.ZodString>;
    query: z.ZodOptional<z.ZodObject<{
        id: z.ZodOptional<z.ZodString>;
        limit: z.ZodOptional<z.ZodNumber>;
        page: z.ZodOptional<z.ZodNumber>;
        pageSize: z.ZodOptional<z.ZodNumber>;
        baseUrl: z.ZodOptional<z.ZodString>;
    }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
        id: z.ZodOptional<z.ZodString>;
        limit: z.ZodOptional<z.ZodNumber>;
        page: z.ZodOptional<z.ZodNumber>;
        pageSize: z.ZodOptional<z.ZodNumber>;
        baseUrl: z.ZodOptional<z.ZodString>;
    }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
        id: z.ZodOptional<z.ZodString>;
        limit: z.ZodOptional<z.ZodNumber>;
        page: z.ZodOptional<z.ZodNumber>;
        pageSize: z.ZodOptional<z.ZodNumber>;
        baseUrl: z.ZodOptional<z.ZodString>;
    }, z.ZodTypeAny, "passthrough">>>;
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
    entityType: z.ZodOptional<z.ZodString>;
    query: z.ZodOptional<z.ZodObject<{
        id: z.ZodOptional<z.ZodString>;
        limit: z.ZodOptional<z.ZodNumber>;
        page: z.ZodOptional<z.ZodNumber>;
        pageSize: z.ZodOptional<z.ZodNumber>;
        baseUrl: z.ZodOptional<z.ZodString>;
    }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
        id: z.ZodOptional<z.ZodString>;
        limit: z.ZodOptional<z.ZodNumber>;
        page: z.ZodOptional<z.ZodNumber>;
        pageSize: z.ZodOptional<z.ZodNumber>;
        baseUrl: z.ZodOptional<z.ZodString>;
    }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
        id: z.ZodOptional<z.ZodString>;
        limit: z.ZodOptional<z.ZodNumber>;
        page: z.ZodOptional<z.ZodNumber>;
        pageSize: z.ZodOptional<z.ZodNumber>;
        baseUrl: z.ZodOptional<z.ZodString>;
    }, z.ZodTypeAny, "passthrough">>>;
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
    entityType: z.ZodOptional<z.ZodString>;
    query: z.ZodOptional<z.ZodObject<{
        id: z.ZodOptional<z.ZodString>;
        limit: z.ZodOptional<z.ZodNumber>;
        page: z.ZodOptional<z.ZodNumber>;
        pageSize: z.ZodOptional<z.ZodNumber>;
        baseUrl: z.ZodOptional<z.ZodString>;
    }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
        id: z.ZodOptional<z.ZodString>;
        limit: z.ZodOptional<z.ZodNumber>;
        page: z.ZodOptional<z.ZodNumber>;
        pageSize: z.ZodOptional<z.ZodNumber>;
        baseUrl: z.ZodOptional<z.ZodString>;
    }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
        id: z.ZodOptional<z.ZodString>;
        limit: z.ZodOptional<z.ZodNumber>;
        page: z.ZodOptional<z.ZodNumber>;
        pageSize: z.ZodOptional<z.ZodNumber>;
        baseUrl: z.ZodOptional<z.ZodString>;
    }, z.ZodTypeAny, "passthrough">>>;
}, z.ZodTypeAny, "passthrough">>;
/**
 * Parsed base query parameters.
 * Subclasses can extend this with additional fields via `parseQuery()`.
 */
type BaseQuery = z.infer<typeof baseQuerySchema>;
/**
 * Navigation context for detail views (prev/next entities).
 */
interface NavigationResult<T> {
    prev: T | null;
    next: T | null;
}
/**
 * Configuration for a BaseEntityDataSource.
 */
interface EntityDataSourceConfig {
    /** Entity type to query (e.g., "post", "deck", "project") */
    entityType: string;
    /** Default sort order for list and navigation queries */
    defaultSort: SortField[];
    /** Default limit for list queries (defaults to 100) */
    defaultLimit?: number;
    /**
     * How to look up a single entity by the `id` query param.
     * - "slug": filter by `metadata.slug` (default)
     * - "id": direct `getEntity()` lookup
     */
    lookupField?: "slug" | "id";
    /** Enable prev/next navigation on detail views (defaults to false) */
    enableNavigation?: boolean;
    /** Max entities to fetch when resolving prev/next navigation (defaults to 1000) */
    navigationLimit?: number;
}
/**
 * Base class for entity datasources that follow the list/detail pattern.
 *
 * Provides:
 * - Query parsing with Zod validation
 * - Detail view: entity lookup (by slug or id), optional prev/next navigation
 * - List view: paginated fetch with sorting
 *
 * Subclasses implement:
 * - `transformEntity()` — convert raw entity to display format
 * - `buildListResult()` — shape the list response
 *
 * Optionally override:
 * - `buildDetailResult()` — shape the detail response (default throws; override
 *   this OR override `fetch()` to handle detail views directly)
 *
 * For datasources with extra query cases (e.g., "latest", "series", "nextInQueue"),
 * override `fetch()` to handle those first, then call `super.fetch()` for the standard path.
 */
declare abstract class BaseEntityDataSource<TEntity extends BaseEntity = BaseEntity, TTransformed = TEntity> implements DataSource {
    protected readonly logger: Logger;
    abstract readonly id: string;
    abstract readonly name: string;
    abstract readonly description: string;
    protected abstract readonly config: EntityDataSourceConfig;
    constructor(logger: Logger);
    /**
     * Transform a raw entity into the display format used by templates.
     * Called for both list items and detail views.
     */
    protected abstract transformEntity(entity: TEntity): TTransformed;
    /**
     * Build the detail response object.
     * Override this if using the base class's standard detail path.
     * Datasources that fully override `fetch()` for detail views need not implement this.
     *
     * @param item - The transformed entity
     * @param navigation - Prev/next entities (null if navigation is disabled)
     */
    protected buildDetailResult(_item: TTransformed, _navigation: NavigationResult<TTransformed> | null): unknown;
    /**
     * Build the list response object.
     * @param items - Transformed entities
     * @param pagination - Pagination info (null if no page param was provided)
     * @param query - The parsed query params (for passing through baseUrl, etc.)
     */
    protected abstract buildListResult(items: TTransformed[], pagination: PaginationInfo | null, query: BaseQuery): unknown;
    /**
     * Parse and validate the incoming query with Zod.
     * Override to support additional query parameters beyond the base set.
     * Use `baseQuerySchema.extend()` or `baseInputSchema` for validation.
     */
    protected parseQuery(query: unknown): {
        entityType: string;
        query: BaseQuery;
    };
    /**
     * Standard fetch implementation: dispatch to detail or list based on query.id.
     *
     * Override to handle custom query cases before falling through to the standard path:
     * ```typescript
     * async fetch<T>(query, outputSchema, context) {
     *   const params = this.parseQuery(query);
     *   if (params.query.latest) {
     *     return this.fetchLatest(outputSchema, context.entityService);
     *   }
     *   return super.fetch(query, outputSchema, context);
     * }
     * ```
     */
    fetch<T>(query: unknown, outputSchema: z.ZodSchema<T>, context: BaseDataSourceContext): Promise<T>;
    /**
     * Fetch a single entity and optionally resolve prev/next navigation.
     */
    protected fetchDetail(id: string, entityService: EntityService): Promise<{
        item: TTransformed;
        navigation: NavigationResult<TTransformed> | null;
    }>;
    /**
     * Fetch a paginated list of entities.
     */
    protected fetchList(query: BaseQuery, entityService: EntityService, listOptions?: Partial<ListOptions>): Promise<{
        items: TTransformed[];
        pagination: PaginationInfo | null;
    }>;
    /**
     * Resolve prev/next navigation for a given entity within the sorted list.
     */
    protected resolveNavigation(entity: TEntity, entityService: EntityService, sortFields?: SortField[]): Promise<NavigationResult<TTransformed>>;
    /**
     * Look up a single entity by id or slug.
     * Uses `config.lookupField` to determine the strategy.
     */
    protected lookupEntity(id: string, entityService: EntityService): Promise<TEntity>;
}

export { BaseEntityDataSource, baseInputSchema, baseQuerySchema };
export type { BaseQuery, EntityDataSourceConfig, NavigationResult, SortField };
