/**
 * `@deepseek-ai/dsh-web-fetch-local`: registers an anonymous public HTTP(S)
 * `WebFetchProvider` with `ctx.web`. A function/namespace plugin (NOT a
 * default-export service): it registers INTO the seam's fetch registry, like the
 * search providers register into the search registry.
 *
 * @module @deepseek-ai/dsh-web-fetch-local
 */

import type { Context } from 'cordis'
import z from 'schemastery'
import type {} from '@deepseek-ai/dsh-web'
import { LocalFetchProvider } from './provider.ts'
import type { LocalFetchLimits } from './provider.ts'

export {
  LOCAL_FETCH_PROVIDER_ID,
  LocalFetchProvider,
} from './provider.ts'
export type { LocalFetchLimits } from './provider.ts'
export { classifyContentType, decoderForCharset, isSameOrigin, parseCharset, validateFetchUrl } from './policy.ts'
export type { FetchableKind } from './policy.ts'

/** Default `User-Agent`: an explicit product agent, never a browser disguise. */
export const DEFAULT_USER_AGENT = 'deepseek-harness/0.0.1 (+https://github.com/deepseek-ai)'

/** Cordis plugin name used by loader diagnostics. */
export const name = 'web-fetch-local'

/** The web seam this provider registers into. */
export const inject = ['web']

export interface Config {
  /** Maximum accepted request URL length. */
  maxUrlLength?: number
  /** Maximum response body size in bytes. */
  maxResponseBytes?: number
  /** Maximum decoded body length in characters. */
  maxBodyChars?: number
  /** Default fetch timeout in milliseconds. */
  timeoutMs?: number
  /** Upper bound for a per-request timeout override. */
  maxTimeoutMs?: number
  /** Maximum number of same-origin redirect hops to follow. */
  maxRedirects?: number
  /** `User-Agent` header sent on every request. */
  userAgent?: string
}

export const Config: z<Config> = z.object({
  maxUrlLength: z.number().default(2048),
  maxResponseBytes: z.number().default(5_000_000),
  maxBodyChars: z.number().default(100_000),
  timeoutMs: z.number().default(30_000),
  maxTimeoutMs: z.number().default(120_000),
  maxRedirects: z.number().default(5),
  userAgent: z.string().default(DEFAULT_USER_AGENT),
})

/** The shape after schemastery applies its defaults to every field. */
type ResolvedConfig = Required<Config>

/** Register the local HTTP(S) fetch provider with `ctx.web`. */
export function apply(ctx: Context, config: Config): void {
  // schemastery (Config) has already filled every defaulted field.
  const resolved = config as ResolvedConfig
  const limits: LocalFetchLimits = {
    maxUrlLength: resolved.maxUrlLength,
    maxResponseBytes: resolved.maxResponseBytes,
    maxBodyChars: resolved.maxBodyChars,
    timeoutMs: resolved.timeoutMs,
    maxTimeoutMs: resolved.maxTimeoutMs,
    maxRedirects: resolved.maxRedirects,
    userAgent: resolved.userAgent,
  }
  ctx.web.registerFetchProvider(new LocalFetchProvider(limits))
}
