import { StopId } from '../stops/stops.js';
import { StopRouteIndex } from '../timetable/route.js';
import { Duration, Time } from '../timetable/time.js';
import { TransferType, TripStop } from '../timetable/timetable.js';
import { AccessPoint } from './access.js';
import type { IRaptorState } from './raptor.js';
/**
 * Sentinel value used in the internal arrival-time array to mark stops not yet reached.
 * 0xFFFF = 65 535 minutes ≈ 45.5 days, safely beyond any realistic transit arrival time.
 */
export declare const UNREACHED_TIME: Time;
export type OriginNode = {
    stopId: StopId;
    arrival: Time;
};
export type AccessEdge = {
    arrival: Time;
    from: StopId;
    to: StopId;
    duration: Duration;
};
/** A boarded transit trip that carries the passenger from one stop to another. */
export type VehicleEdge = TripStop & {
    arrival: Time;
    hopOffStopIndex: StopRouteIndex;
    /** modeling in-seat transfer */
    continuationOf?: VehicleEdge;
};
/** A walking or guaranteed connection between two stops. */
export type TransferEdge = {
    arrival: Time;
    from: StopId;
    to: StopId;
    type: TransferType;
    minTransferTime?: Duration;
};
export type RoutingEdge = OriginNode | AccessEdge | VehicleEdge | TransferEdge;
/** The earliest arrival at a stop together with how many legs were needed to reach it. */
export type Arrival = {
    arrival: Time;
    legNumber: number;
};
/**
 * Encapsulates all mutable state for a single RAPTOR routing query.
 */
export declare class RoutingState implements IRaptorState {
    /** Origin stop IDs for this query. */
    origins: StopId[];
    /** Destination stop IDs for this query. */
    readonly destinations: StopId[];
    /**
     * Routing graph: the best edge used to reach each stop, per round.
     * Indexed as graph[round][stopId]. Entries are undefined for stops not
     * reached in that particular round.
     */
    readonly graph: (RoutingEdge | undefined)[][];
    /**
     * Earliest arrival time at each stop (minutes from midnight), indexed by stop ID.
     * Pre-filled with UNREACHED_TIME; updated exclusively through updateArrival().
     * Not readonly so that fromTestData() can replace the arrays directly.
     */
    private earliestArrivalTimes;
    /**
     * Round number (leg count) in which each stop was first reached, indexed by stop ID.
     * Zero-initialized by the typed array; updated exclusively through updateArrival().
     * Not readonly so that fromTestData() can replace the arrays directly.
     */
    private earliestArrivalLegs;
    /**
     * Fast O(1) membership test for destination stops.
     * Built once at construction time from the `destinations` array.
     */
    private readonly destinationSet;
    /**
     * Cached best arrival time at any destination stop, kept up-to-date by
     * {@link updateArrival} so that destination pruning is always O(1).
     */
    private _destinationBest;
    /**
     * Maximum arrival time allowed for this run. Defaults to UNREACHED_TIME when
     * the query has no maxDuration limit.
     */
    maxArrivalTime: Time;
    /**
     * Query-level maximum duration, retained so resetFor() can recompute the
     * absolute max arrival time for each departure-time iteration.
     */
    private readonly maxDuration?;
    /**
     * Every stop that has received an arrival improvement during the current run,
     * in the order the improvements occurred.  Used by {@link resetFor} to clear
     * only the touched entries instead of scanning the entire array.
     */
    private readonly reachedStops;
    constructor(departureTime: Time, destinations: StopId[], accessPaths: AccessPoint[], nbStops: number, maxRounds?: number, maxDuration?: Duration);
    /**
     * Seeds round-0 arrivals and {@link origins} from a set of access paths.
     * Called by the constructor and by {@link resetFor}.
     * Assumes {@link earliestArrivalTimes} and {@link graph}[0] are already
     * allocated and in their "cleared" state (all entries at UNREACHED_TIME /
     * undefined) before this method runs.
     */
    private seedAccessPaths;
    /** Total number of stops in the timetable */
    get nbStops(): number;
    /**
     * Returns the earliest known arrival time at a stop.
     * Returns UNREACHED_TIME if the stop has not been reached yet.
     */
    arrivalTime(stop: StopId): Time;
    /**
     * Earliest arrival at any destination stop; {@link UNREACHED_TIME} if none
     * has been reached yet. Updated automatically by {@link updateArrival}. O(1).
     */
    get destinationBest(): Time;
    /**
     * In standard RAPTOR the improvement bound is simply the per-run earliest
     * arrival; the `round` argument is ignored.
     */
    improvementBound(_round: number, stop: StopId): Time;
    /** No-op in standard RAPTOR — there are no shared cross-run labels to propagate. */
    initRound(_round: number): void;
    /**
     * Records a new earliest arrival at a stop.
     *
     * @param stop The stop that was reached.
     * @param time The arrival time in minutes from midnight.
     * @param leg  The round number (number of transit legs taken so far).
     */
    updateArrival(stop: StopId, time: Time, leg: number): void;
    /**
     * Resets this state for a new departure-time iteration **without
     * reallocating** the underlying arrays.
     *
     * Only the stops recorded in {@link reachedStops} are touched — all other
     * entries are already at their initial bound values.
     *
     * After this call the state is equivalent to a freshly constructed
     * {@link RoutingState} for the given `depTime` and `accessPaths`.
     *
     * @param depTime     New origin departure time.
     * @param accessPaths Access legs for this departure-time slot.
     */
    resetFor(depTime: Time, accessPaths: AccessPoint[]): void;
    /**
     * Iterates over every stop that has been reached, yielding its stop ID,
     * earliest arrival time, and the number of legs taken to reach it.
     *
     * Unreached stops (those still at UNREACHED_TIME) are skipped entirely.
     *
     * @example
     * ```ts
     * for (const { stop, arrival, legNumber } of routingState.arrivals()) {
     *   console.log(`Stop ${stop}: arrived at ${arrival} after ${legNumber} leg(s)`);
     * }
     * ```
     */
    arrivals(): Generator<{
        stop: StopId;
        arrival: Time;
        legNumber: number;
    }>;
    /**
     * Finds the earliest arrival time at any stop from a given set of destinations.
     *
     * @param routingState The routing state containing arrival times and destinations.
     * @returns The earliest arrival time among the provided destinations.
     */
    earliestArrivalAtAnyDestination(): Time;
    /**
     * Returns the earliest arrival at a stop as an {@link Arrival} object,
     * or undefined if the stop has not been reached.
     */
    getArrival(stop: StopId): Arrival | undefined;
    /**
     * Returns `true` if `stop` is one of the query's destination stops.
     * O(1) — backed by a `Set` built at construction time.
     */
    isDestination(stop: StopId): boolean;
    /**
     * Creates a {@link RoutingState} from fully-specified raw data.
     *
     * Use this in tests instead of constructing the object through the production
     * constructor, which is designed for incremental algorithm state.
     *
     * @param nbStops  Total number of stops (sets array sizes).
     * @param origins  Origin stop IDs.
     * @param destinations  Destination stop IDs.
     * @param arrivals  Each entry is `[stop, time, leg]` — the earliest arrival
     *                  time in minutes and the round number for one stop.
     * @param graph  One element per round. Each round is a sparse list of
     *               `[stop, edge]` pairs; stops absent from the list are
     *               left as `undefined` in the dense output array.
     *
     * @internal For use in tests only.
     */
    static fromTestData({ nbStops, origins, destinations, arrivals, graph, }: {
        nbStops: number;
        origins?: StopId[];
        destinations?: StopId[];
        arrivals?: [stop: StopId, time: Time, leg: number][];
        graph?: [stop: StopId, edge: RoutingEdge][][];
    }): RoutingState;
}
