import type { BaseQueryFormat, BaseQueryResult } from '../../base-query-format';
import Joi from 'joi';
import type { NodeId } from '../../../r-bridge/lang-4.x/ast/model/processing/node-id';
import type { ParsedQueryLine } from '../../query';
import { type OutputFormatter } from '../../../util/text/ansi';
import { type VersionString } from '../../../util/r-version';
import type { ReplOutput } from '../../../cli/repl/commands/repl-main';
import { VersionSelection, type FlowrConfig } from '../../../config';
import { executeGuessDepVersionsQuery } from './guess-dep-versions-query-executor';
import type { ConstraintSource, DerivedConstraint, OrphanReason } from '../../../project/dependency-version-space';
import type { RVersionOrigin } from '../../../project/context/flowr-analyzer-context';
/**
 * Guesses the possible version range of every dependency of a project by combining what the project *declares*
 * (a `DESCRIPTION` range, an `rproject.toml` entry, a lockfile pin, and their transitive constraints) with what
 * the code actually *does* (which package functions it calls and with which arguments, matched against the
 * {@link https://github.com/flowr-analysis/flowr/wiki/Signature-Database|signature database}). A named argument
 * a function only gained in some version raises the lower bound ("this parameter only existed from version X.Y,
 * so it must be at least X.Y"); an optional `date` caps every guess to releases available at that point in time,
 * and base-R packages are additionally bounded by the assumed/declared R version.
 */
export interface GuessDepVersionsQuery extends BaseQueryFormat {
    readonly type: 'guess-dep-versions';
    /** restrict the guess to these packages; omit to guess for every declared and used dependency */
    readonly packages?: readonly string[];
    /** only consider versions released on or before this day, written `YYYY.MM.DD` (also `YYYY` or `YYYY.MM`) */
    readonly date?: string;
    /** cap the number of candidate versions listed per dependency in the result (default {@link DefaultCandidateCap}) */
    readonly maxCandidates?: number;
    /** bound both fixpoint loops (mutual transitive refinement and arc consistency), default {@link DefaultFixpointIterations} */
    readonly maxIterations?: number;
    /** ignore the project's declared constraints (`DESCRIPTION` ranges, lockfile pins, transitive requirements); guess purely from code usage and the date/R bounds */
    readonly clean?: boolean;
    /** exclude these evidence sources from consideration entirely (repl: `--disabled` followed by their one-letter codes, e.g. `--disabled ds` for declared+signature) */
    readonly disabled?: readonly ConstraintSource[];
    /** also explode the guessed space into concrete per-dependency version assignments (see {@link GuessExplodeOptions}) */
    readonly explode?: GuessExplodeOptions;
}
/** how to explode the guessed constraint space into concrete version assignments */
export interface GuessExplodeOptions {
    /** iterate each dependency's versions newest-first (default) or oldest-first */
    readonly order?: 'newest' | 'oldest';
    /** a version to prefer per dependency when it survives the constraints (package name to version) */
    readonly prefer?: Readonly<Record<string, VersionString>>;
    /** cap the number of combinations considered; the ones that cannot be loaded together are skipped, not returned */
    readonly limit?: number;
}
/** one concrete version choice per resolvable dependency (`package -> version`) */
export interface VersionAssignmentView {
    readonly versions: Readonly<Record<string, VersionString>>;
    /** see {@link VersionAssignment.unverified}: requirements on packages this assignment does not choose */
    readonly unverified?: readonly string[];
}
/** the default cap on how many surviving candidate versions are listed per dependency */
export declare const DefaultCandidateCap = 16;
/** where a single bound on a dependency's version came from (the {@link DerivedConstraint} source, from the resolver) */
export type GuessEvidenceSource = ConstraintSource;
/**
 * The resolver's {@link DerivedConstraint} with its {@link DerivedConstraint.at|call site} resolved to a readable
 * location, so the evidence answers not only "it must be `>= 4.2.0` because it calls `filter(.by=)`" but also where.
 */
export interface GuessVersionEvidence extends DerivedConstraint {
    /** the location of the call that carried the evidence, e.g. `12:3` or `helper.R:12:3` */
    readonly location?: string;
}
/** why a package is reported as an orphan: the call that would be undefined without it, and how it was picked */
export interface OrphanEvidenceView {
    /** the undefined function that is called, e.g. `ggplot` */
    readonly function: string;
    /** where it is called, e.g. `12:3` */
    readonly location?: string;
    /** why this package and not another exporter of the name */
    readonly reason: OrphanReason;
    /** how many packages export the name */
    readonly exporters: number;
}
/** one package an orphan call could have meant instead, with the versions of it that fit those calls */
export interface OrphanAlternativeView {
    readonly package: string;
    /** the version range of this package that would accept the orphan calls, in the notation {@link GuessedDependency.range} uses */
    readonly range: string;
    readonly minVersion?: string;
    readonly maxVersion?: string;
    readonly candidateCount: number;
    readonly totalVersions: number;
}
/** the guessed version range of one dependency */
export interface GuessedDependency {
    readonly package: string;
    /** whether this is an R-core / base package (then its version *is* the R version) */
    readonly base: boolean;
    /** the raw version constraints declared for the package (`>= 1.0.0`, a lockfile pin, ...) */
    readonly declaredConstraints: readonly string[];
    /** the resulting range, e.g. `>=1.0.0 <=1.1.4`, an exact `1.1.4`, or `*` when nothing constrains it */
    readonly range: string;
    readonly minVersion?: VersionString;
    readonly maxVersion?: VersionString;
    /** how many candidate versions survived every constraint */
    readonly candidateCount: number;
    /** how many versions the database carries in total for the package (the history the candidates are drawn from) */
    readonly totalVersions?: number;
    /** the surviving candidate versions, ascending (capped, see {@link GuessDepVersionsQuery.maxCandidates}) */
    readonly candidates?: readonly VersionString[];
    /** whether the listed {@link candidates} were capped */
    readonly truncated?: boolean;
    readonly evidence: readonly GuessVersionEvidence[];
    /** set when the constraints contradict each other so that no version can satisfy them all */
    readonly unsatisfiable?: boolean;
    /** the other packages this one shares a version with, so its range is not independent of theirs */
    readonly linkedWith?: readonly string[];
    /**
     * The other packages whose version requirements this one's version choice interacts with, so the two cannot be
     * picked independently (`A 0.2.5` requiring `B == 0.2.1` while `A 0.3.0` requires `B == 0.3.2`). A partner marked
     * `(partial)` only requires (or is required by) this package in some of their versions.
     */
    readonly coupledWith?: readonly string[];
    /**
     * Whether the analyzed code actually uses this package (a declared-but-never-used dependency is unconstrained):
     * either a direct call, or the project's own NAMESPACE registering an S3 method for a class this package OWNS
     * (see `PackageSignatureSource.classOwner`), e.g. tseries's `S3method("as.irts","zoo")` marks `zoo` used with
     * no direct `zoo::`/`library(zoo)` call.
     */
    readonly used?: boolean;
    /**
     * Set to `false` when the signature database has no record of the package at all (e.g. a Bioconductor package),
     * distinguishing it from one the database carries but cannot constrain. Such a package has no `minVersion`/`maxVersion`
     * and never appears in {@link GuessDepVersionsQueryResult.assignments}, so a consumer should resolve it by other means.
     */
    readonly known?: boolean;
    /**
     * Set to `false` when nothing narrowed the package: every version the database holds survives, so the range
     * merely restates what is available. Its {@link minVersion}/{@link maxVersion} then say nothing about the code
     * (an era read off the minimum would be the database's oldest release, not the script's), which a range that
     * happens to end at the newest version does not reveal on its own.
     */
    readonly constrained?: boolean;
    /**
     * Set when this package was inferred purely from *orphan* calls: bare calls (`ggplot()`) that flowR could not
     * resolve and that no loaded package defines, but whose name is exported by exactly this one package in the
     * signature database. The symbol would be undefined were the package not loaded, so a downstream handler may
     * attach `library(package)`. See {@link orphanFunctions} for the calls that implicated it.
     */
    readonly orphan?: boolean;
    /** the undefined orphan function names that inferred this package (only set when {@link orphan}), e.g. `['ggplot']` */
    readonly orphanFunctions?: readonly string[];
    /** per {@link orphanFunctions} entry, where the undefined call is and why it was pinned on this package */
    readonly orphanEvidence?: readonly OrphanEvidenceView[];
    /**
     * The other packages that export the {@link orphanFunctions}, each with the versions of it that would fit the
     * calls. Attributing an orphan is a guess: the most downloaded exporter wins, and these are the ones it beat,
     * so whoever reads the result can pick another. Ordered as the guess ranked them, best first.
     */
    readonly orphanAlternatives?: readonly OrphanAlternativeView[];
}
export interface GuessDepVersionsQueryResult extends BaseQueryResult {
    readonly dependencies: readonly GuessedDependency[];
    /** the effective date cutoff that was applied (ISO `YYYY-MM-DD`), if any */
    readonly dateCutoff?: string;
    /** the R version the guess assumed when bounding base-R packages, if known */
    readonly rVersion?: string;
    /**
     * Where {@link rVersion} comes from. An `engine` version is the R installation running the analysis, which
     * bounds the guess without saying anything about the analyzed code, unlike a `config` pin or project `metadata`.
     */
    readonly rVersionOrigin?: RVersionOrigin;
    /** the configured version-selection policy the sample illustrates (newest by default; see `solver.sigdb.versionSelection`) */
    readonly versionSelection?: VersionSelection;
    /** version tuples that satisfy every interdependency (the base/R hub counted against each dependency) */
    readonly runnableCombinations?: number;
    /** the whole version space those tuples are drawn from (product of each counted factor's total versions) */
    readonly possibleCombinations?: number;
    /**
     * The tuples the *declared* constraints alone leave, i.e. what the project already pins down before code usage and
     * interdependencies are taken into account. Set only when something is declared and the `declared` source is active,
     * so `runnableCombinations` relative to it says how much the guess added.
     */
    readonly declaredCombinations?: number;
    /** groups of packages interlinked to one shared version (the base/R group plus any configured groups), so their versions are not independent */
    readonly linkedGroups?: readonly (readonly string[])[];
    /** concrete version assignments, present when {@link GuessDepVersionsQuery.explode} was requested (most-preferred first) */
    readonly assignments?: readonly VersionAssignmentView[];
    /** a note, e.g. when the signature database is unavailable */
    readonly message?: string;
}
/** parse a repl line: `[(clean[:<=YYYY])] [pkg ...] [--date YYYY.MM.DD] [--max N] [--iterations N] [--disabled <letters>] [--explode [--oldest] [--limit N] [--prefer pkg=ver ...]]` */
declare function guessDepVersionsLineParser(_output: ReplOutput, line: readonly string[], _config: FlowrConfig): ParsedQueryLine<'guess-dep-versions'>;
export declare const GuessDepVersionsQueryDefinition: {
    readonly title: "Guess Dependency Versions Query";
    readonly executor: typeof executeGuessDepVersionsQuery;
    readonly asciiSummarizer: (formatter: OutputFormatter, _analyzer: import("../../../project/flowr-analyzer").ReadonlyFlowrAnalysisProvider<import("../../../r-bridge/parser").KnownParser>, queryResults: BaseQueryResult, result: string[], _query: readonly import("../../query").Query[]) => true;
    readonly fromLine: typeof guessDepVersionsLineParser;
    readonly syntax: "@guess-dep-versions [<pkg> ...] [(clean | <=YYYY.MM.DD)] [--date YYYY.MM.DD] [--max <n>] [--iterations <n>] [--disabled <letters>] [--explode [--oldest] [--limit <n>] [--prefer <pkg>=<ver>]] <code | file://path>";
    readonly schema: Joi.ObjectSchema<any>;
    readonly flattenInvolvedNodes: () => NodeId[];
};
export {};
