/**
 * {@link Dataset} ties the embedded records together: it owns every
 * {@link Collection}, builds the cross-entity indexes once, and is the `this`
 * the linked views resolve against.
 *
 * @packageDocumentation
 */
import type { DeploymentPattern, Detachment, Enhancement, ForceDisposition, GameVersion, InteractionFlag, LeaderAttachment, Mission, MissionMatchup, Phase, ResourcePool, SecondaryCard, Stratagem, TerrainLayout, TerrainTemplate, TimingFlag, Unit, UnitComposition, Wargear, WargearOption, WeaponKeyword } from "../generated.js";
import { Collection } from "./collection.js";
import { AbilityView, FactionView, UnitView, WeaponKeywordView, WeaponView } from "./entities.js";
import { type RawData } from "./types.js";
import { type ResolvedPiece } from "../terrain/resolve.js";
import type { Buff, BuffSource, EngineContext } from "../cruncher/buffs.js";
import { type EligibilityInput, type EligibleAbility } from "../abilities-resolver/index.js";
/**
 * One toggleable buff lever for damage analysis: the contributions it adds and
 * whether it's on by default. `enabled` is `true` for buffs that always apply
 * (intrinsic keywords, unconditional abilities) and `false` for player
 * decisions — stratagems (CP cost) and activatable gates (dice-pool options,
 * `choice` branches, timing-gated activations). A consumer flips `enabled`,
 * then crunches the enabled subset; an optimizer searches it.
 *
 * @see {@link Dataset.stackableBuffsFor}
 */
export type StackableBuff = {
    /** Stable toggle id (stable across re-enumeration of the same input). */
    id: string;
    /** Human label for the lever. */
    label: string;
    /** Contributions this lever adds when enabled (≥1). */
    buffs: Buff[];
    /** Default selection state. */
    enabled: boolean;
    /** Where the lever came from. */
    source: BuffSource;
    /** Id of the mutually-limited {@link StackableBuffGroup} this belongs to, if any. */
    group?: string;
};
/** A pool of {@link StackableBuff} levers limited to `maxActivations` at once. */
export type StackableBuffGroup = {
    id: string;
    label: string;
    maxActivations: number;
};
/** The whole dataset, with linked accessors over every entity collection. */
export declare class Dataset {
    readonly units: Collection<Unit, UnitView>;
    readonly weapons: Collection<RawData["weapons"][number], WeaponView>;
    readonly weaponKeywords: Collection<WeaponKeyword, WeaponKeywordView>;
    readonly factions: Collection<RawData["factions"][number], FactionView>;
    readonly abilities: Collection<RawData["abilities"][number], AbilityView>;
    readonly detachments: Collection<Detachment, Detachment>;
    readonly enhancements: Collection<Enhancement, Enhancement>;
    readonly stratagems: Collection<Stratagem, Stratagem>;
    readonly wargearOptions: Collection<WargearOption, WargearOption>;
    readonly wargear: Collection<Wargear, Wargear>;
    readonly missions: Collection<Mission, Mission>;
    readonly missionMatchups: Collection<MissionMatchup, MissionMatchup>;
    readonly missionCards: Collection<SecondaryCard, SecondaryCard>;
    readonly deploymentPatterns: Collection<DeploymentPattern, DeploymentPattern>;
    readonly forceDispositions: Collection<ForceDisposition, ForceDisposition>;
    readonly terrainTemplates: Collection<TerrainTemplate, TerrainTemplate>;
    readonly terrainLayouts: Collection<TerrainLayout, TerrainLayout>;
    readonly resourcePools: Collection<ResourcePool, ResourcePool>;
    readonly leaderAttachments: readonly LeaderAttachment[];
    readonly unitCompositions: readonly UnitComposition[];
    readonly gameVersions: readonly GameVersion[];
    readonly timingFlags: readonly TimingFlag[];
    readonly interactionFlags: readonly InteractionFlag[];
    readonly phaseMappings: readonly RawData["phaseMappings"][number][];
    /** `source_type:source_id` → unioned phases. */
    private readonly phaseIndex;
    /** ability id → units that list it. */
    private readonly unitsByAbility;
    /** weapon id → units that list it. */
    private readonly unitsByWeapon;
    /** weapon-keyword id → weapons whose profiles reference it. */
    private readonly weaponsByKeyword;
    /** unit id → wargear options authored for it (declared order preserved). */
    private readonly wargearOptionsByUnit;
    constructor(raw?: RawData);
    /** The dataset built from the package's embedded data. */
    static embedded(): Dataset;
    /** Phases a source acts in, unioned across its phase-mappings. */
    phasesFor(sourceType: string, sourceId: string): Phase[];
    /**
     * Resolve a terrain layout to absolute board-space vertices using this
     * dataset's embedded terrain-template catalog — the layout-id →
     * renderable-geometry hop. Mirror of Rust `Dataset::resolve_terrain`; the
     * geometry is pinned by the `terrain-resolver` conformance corpus.
     */
    resolveTerrain(layout: TerrainLayout): ResolvedPiece[];
    /**
     * The terrain layouts a deployment pattern recommends, in declared order,
     * skipping any ids absent from the dataset.
     */
    recommendedTerrainLayouts(pattern: DeploymentPattern): TerrainLayout[];
    /** Units that list the given ability id. */
    unitsWithAbility(abilityId: string): UnitView[];
    /** Units that list the given weapon id. */
    unitsWithWeapon(weaponId: string): UnitView[];
    /** Weapons whose profiles reference the given weapon-keyword id. */
    weaponsWithKeyword(keywordId: string): WeaponView[];
    /**
     * Wargear options authored for the given unit, in declared order. Mirror of
     * Rust `Dataset::wargear_options_of`. Empty for a unit with no options.
     */
    wargearOptionsOf(unit: Unit): WargearOption[];
    /**
     * Leaders whose leader-attachment data lists `bodyguardUnitId` among its
     * eligible body units, sorted by name. The attachment is stored on the
     * leader pointing down to its bodyguards, so answering "which leaders can
     * attach to this unit?" means scanning the attachment list. Returns an empty
     * array for a unit that no leader can attach to (including leader units).
     */
    leadersAttachableTo(bodyguardUnitId: string): UnitView[];
    /**
     * The inverse of {@link leadersAttachableTo}: the body units the given
     * leader can attach to, sorted by name. Scans the same leader-attachment
     * data from the leader's side (`leader_id` matches; resolve each
     * `eligible_bodyguard_ids` entry), deduped by id. Empty for a non-leader
     * unit. Together the two queries give the bidirectional attachment graph the
     * SPA needs to offer a partner dropdown from either end.
     */
    bodyguardsAttachableFrom(leaderUnitId: string): UnitView[];
    /**
     * Enumerate every ability that could apply to the given unit in `phase`,
     * grouped by source. The SPA uses this to render the abilities pane.
     */
    eligibleAbilities(input: EligibilityInput, phase: Phase): EligibleAbility[];
    /**
     * Attacker-perspective {@link Buff} stack for a (unit, phase) combination:
     * intrinsic weapon-profile keywords plus every eligible ability whose DSL
     * effect translates to an attacker-side buff (army, detachment, unit,
     * attached members, support, plus any stratagems the caller has opted into).
     *
     * The result includes only buffs the buff layer can express today — the
     * `unsupported` half of the DSL→Buff translation is dropped here so callers
     * who just want the stack don't need to thread diagnostics through. Use
     * {@link AbilityView.describeBuffs} when you need the diagnostics for an
     * individual ability. Symmetric to {@link defensiveBuffsFor}, which walks
     * the same eligibility set under target perspective.
     */
    buffsFor(input: EligibilityInput & {
        weaponProfiles?: {
            weaponId: string;
            profileIndex: number;
        }[];
        /** Stratagem ids the caller has opted into spending CP on. */
        optedInStratagemIds?: string[];
    }, context: EngineContext): Buff[];
    /**
     * Defender-perspective buff stack for the chosen unit: walks the same
     * eligible-abilities set as {@link buffsFor} but translates each ability's
     * DSL effect as defensive (FNP, save mods from `stat-modifier Sv`,
     * toughness mods from `stat-modifier T`, save rerolls, incoming hit
     * penalties from `bs-modifier`). Use this when the chosen unit is being
     * crunched as the *target* — the engine reads `feelNoPain`/`saveMod`/
     * `toughnessMod` out of `resolveBuffs` so wiring the result into `crunch`
     * just means concatenating onto the existing `buffs` array.
     *
     * `weaponProfiles` are ignored under target perspective — weapon-keyword
     * effects ride with the firing weapon, not the receiving unit.
     */
    defensiveBuffsFor(input: EligibilityInput & {
        optedInStratagemIds?: string[];
    }, context: EngineContext): Buff[];
    /**
     * Enumerate every attacker-side buff a unit could stack in `context` as a
     * list of toggleable levers, plus the activation groups that limit them.
     *
     * Unlike {@link buffsFor} — which returns only the buffs that auto-apply —
     * this surfaces the *player decisions* too: stratagems, and the activatable
     * gates the DSL models as dice-pool options, `choice` branches, or
     * timing-gated activations (e.g. Blessings of Khorne's three keyword grants).
     * Each lever carries `enabled` (its default state) and, where it's part of a
     * limited pool, a `group` id whose {@link StackableBuffGroup} caps how many
     * can fire at once. The intended loop:
     *
     * ```ts
     * const { buffs } = ds.stackableBuffsFor(input, ctx);
     * const chosen = buffs.filter(b => b.enabled).flatMap(b => b.buffs);
     * crunch({ ...profiles, buffs: chosen, context: ctx }, ds);
     * ```
     *
     * Target/phase conditions a lever still carries (e.g. "vs Infantry") ride on
     * each buff's `applicableWhen`, so toggling it on is always safe — the
     * resolver gates it per-target.
     */
    stackableBuffsFor(input: EligibilityInput & {
        weaponProfiles?: {
            weaponId: string;
            profileIndex: number;
        }[];
    }, context: EngineContext): {
        buffs: StackableBuff[];
        groups: StackableBuffGroup[];
    };
    /** Shared implementation for buffsFor / defensiveBuffsFor. */
    private collectBuffs;
    private buildIndexes;
}
//# sourceMappingURL=dataset.d.ts.map