import type { ITtscPluginCapabilities } from "./ITtscPluginCapabilities";
import type { ITtscPluginContributor } from "./ITtscPluginContributor";
import type { TtscPluginStage } from "./TtscPluginStage";
/**
 * Runtime descriptor returned by a ttsc plugin module.
 *
 * A JavaScript plugin entry in `compilerOptions.plugins[]` is only the loading
 * point. After ttsc resolves that JavaScript module, the module must return an
 * `ITtscPlugin` descriptor either directly, as `default`, as `plugin`, or from
 * a descriptor factory.
 *
 * The descriptor tells ttsc which Go source package implements the native
 * behavior and where it participates in the TypeScript-Go pipeline. ttsc then
 * builds the Go source lazily with the bundled Go toolchain and passes the
 * original project plugin config through `--plugins-json`.
 */
export interface ITtscPlugin {
    /**
     * Optional human-readable label used in diagnostics and build messages.
     * Routing is never based on this value.
     */
    name?: string;
    /**
     * Go package directory, or a `go.mod` file, that ttsc lazily builds.
     *
     * Ttsc accepts source only. It does not accept a prebuilt binary path: the
     * package-local Go compiler builds this source into the ttsc plugin cache on
     * demand.
     *
     * Directory sources search upward at most 3 parent directories for `go.mod`;
     * direct `go.mod` sources build the module root as `.`. A `package main`
     * source builds as an executable sidecar; a non-`main` transform source is
     * linked into the selected native host and must register through
     * `driver.RegisterPlugin`.
     *
     * Relative paths are resolved from the consumer project root. Package
     * descriptors published in npm packages should normally return absolute paths
     * based on their own descriptor directory — derive them from a factory's
     * `context.dirname` (the load-mode-independent replacement for `__dirname`,
     * which is undefined when ttsc loads the descriptor through ttsx or as ESM).
     *
     * Common layouts:
     *
     * - `source: path.resolve(context.dirname, "src")` when a package descriptor
     *   keeps its Go command in `src`.
     * - `source: path.resolve(context.dirname, "plugin")` when a published package
     *   has a dedicated Go plugin folder.
     * - `source: "plugin"` only for project-local descriptors where the consumer
     *   project root owns the `plugin` directory.
     * - `source: "go.mod"` when the consumer project root itself is the command
     *   package; use an absolute `go.mod` path for npm package descriptors.
     */
    source: string;
    /**
     * Other transform plugin names or transform specifiers that this native
     * source can execute in the same compiler pass.
     *
     * Package auto-discovery may find multiple transform packages that must share
     * one emit host. When one descriptor lists another entry here, ttsc keeps the
     * original plugin config in `--plugins-json` but points the composed entry at
     * this descriptor's native source so both entries resolve to one binary.
     */
    composes?: string[];
    /**
     * Pipeline stage implemented by the native source.
     *
     * Omit this field for normal compiler-transform plugins. The only explicit
     * non-transform stage is `"check"`. Check-stage plugins receive `check`
     * during normal builds and may implement `fix` for `ttsc fix` and `format`
     * for `ttsc format`.
     *
     * @default "transform"
     */
    stage?: TtscPluginStage;
    /**
     * Optional host behaviors declared by the native source.
     *
     * Ttsc carries a few cross-cutting command-line flags (`--singleThreaded`,
     * `--checkers`, …) the lint sidecar parses but a typical third-party
     * transform host does not. Capabilities also cover opt-in host protocols such
     * as LSP sidecar probing. Every capability defaults to `false`.
     *
     * @see ITtscPluginCapabilities
     */
    capabilities?: ITtscPluginCapabilities;
    /**
     * Whether a check-stage sidecar reports the normal TypeScript diagnostics for
     * the project as part of its `check` subcommand.
     *
     * Leave this unset for ordinary check plugins that only report their own
     * diagnostics; ttsc will keep running a separate `tsgo --noEmit` guard so
     * TypeScript errors are not suppressed. Set it only when the sidecar builds
     * the project Program and emits the same TypeScript diagnostics the guard
     * would have produced.
     */
    reportsTypeScriptDiagnostics?: boolean;
    /**
     * Additional Go source packages to statically link into this plugin's binary
     * at build time ("plugin-within-plugin" composition).
     *
     * Each contributor's Go source directory is copied into the scratch build
     * tree as a sub-package of this plugin's module and reached by a synthesized
     * blank import. The contributor's `init()` runs before the host binary's
     * `main`, registering whatever state the host expects to find at startup
     * (e.g. lint rules through `github.com/samchon/ttsc/packages/lint/rule`).
     *
     * Differs from `composes`:
     *
     * - `composes` is horizontal — many plugin entries dispatch to one binary by
     *   name. Each entry is still a top-level `compilerOptions.plugins[]` citizen
     *   with its own lifecycle slot.
     * - `contributors` is vertical — one binary statically links additional Go
     *   sources that never appear as top-level plugin entries. The contributing
     *   npm packages are discovered through the host plugin's own config file
     *   (e.g. `lint.config.ts` for `@ttsc/lint`).
     *
     * Constraints:
     *
     * - Contributors ship Go source as a package (no `go.mod`); the host plugin's
     *   module supplies every transitive Go dependency. This is also a
     *   supply-chain feature — contributors cannot pull in arbitrary Go modules
     *   at build time.
     * - Contributor source paths must be absolute (the host plugin's JS factory
     *   typically resolves them through `require.resolve`).
     * - Contributor names are used as the sub-package import suffix and must be
     *   unique within a single plugin build.
     */
    contributors?: ITtscPluginContributor[];
}
