import { readFileSync } from 'node:fs';
import { gunzipSync } from 'node:zlib';
import { resolve, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
/**
 * Expands a compact altitude constraint into the full interface.
 */
function expandAltitudeConstraint(c) {
    const ac = {
        descriptor: c.d,
        primaryFt: c.p,
    };
    if (c.s !== undefined) {
        ac.secondaryFt = c.s;
    }
    return ac;
}
/**
 * Expands a compact speed constraint into the full interface.
 */
function expandSpeedConstraint(c) {
    return { descriptor: c.d, speedKt: c.s };
}
/**
 * Expands a compact leg into the full {@link ProcedureLeg} interface.
 */
function expandLeg(c) {
    const leg = { pathTerminator: c.pt };
    if (c.fi !== undefined) {
        leg.fixIdentifier = c.fi;
    }
    if (c.cat !== undefined) {
        leg.category = c.cat;
    }
    if (c.lat !== undefined) {
        leg.lat = c.lat;
    }
    if (c.lon !== undefined) {
        leg.lon = c.lon;
    }
    if (c.ir !== undefined) {
        leg.icaoRegionCode = c.ir;
    }
    if (c.ac !== undefined) {
        leg.altitudeConstraint = expandAltitudeConstraint(c.ac);
    }
    if (c.sc !== undefined) {
        leg.speedConstraint = expandSpeedConstraint(c.sc);
    }
    if (c.crs !== undefined) {
        leg.courseDeg = c.crs;
    }
    if (c.ct === 1) {
        leg.courseIsTrue = true;
    }
    if (c.dist !== undefined) {
        leg.distanceNm = c.dist;
    }
    if (c.hold !== undefined) {
        leg.holdTimeMin = c.hold;
    }
    if (c.rn !== undefined) {
        leg.recommendedNavaid = c.rn;
    }
    if (c.rnIr !== undefined) {
        leg.recommendedNavaidIcaoRegionCode = c.rnIr;
    }
    if (c.th !== undefined) {
        leg.thetaDeg = c.th;
    }
    if (c.rh !== undefined) {
        leg.rhoNm = c.rh;
    }
    if (c.rnp !== undefined) {
        leg.rnpNm = c.rnp;
    }
    if (c.td !== undefined) {
        leg.turnDirection = c.td;
    }
    if (c.ar !== undefined) {
        leg.arcRadiusNm = c.ar;
    }
    if (c.cf !== undefined) {
        leg.centerFix = c.cf;
    }
    if (c.cfIr !== undefined) {
        leg.centerFixIcaoRegionCode = c.cfIr;
    }
    if (c.iaf === 1) {
        leg.isInitialApproachFix = true;
    }
    if (c.ifx === 1) {
        leg.isIntermediateFix = true;
    }
    if (c.faf === 1) {
        leg.isFinalApproachFix = true;
    }
    if (c.facf === 1) {
        leg.isFinalApproachCourseFix = true;
    }
    if (c.map === 1) {
        leg.isMissedApproachPoint = true;
    }
    if (c.fo === 1) {
        leg.isFlyover = true;
    }
    return leg;
}
/**
 * Expands a compact transition into the full interface.
 */
function expandTransition(c) {
    return {
        name: c.nm,
        legs: c.lg.map(expandLeg),
    };
}
/**
 * Expands a compact common route into the full interface.
 */
function expandCommonRoute(c) {
    const route = {
        legs: c.lg.map(expandLeg),
        airports: c.apt,
    };
    if (c.rw !== undefined) {
        route.runway = c.rw;
    }
    return route;
}
/**
 * Expands a compact missed approach into the full interface.
 */
function expandMissedApproach(c) {
    return { legs: c.lg.map(expandLeg) };
}
/**
 * Expands a compact procedure record into the full {@link Procedure}
 * interface, populating IAP-specific fields when present.
 */
function expandProcedure(c) {
    const p = {
        name: c.nm,
        identifier: c.id,
        type: c.tp,
        airports: c.apt,
        commonRoutes: c.cr.map(expandCommonRoute),
        transitions: c.tr.map(expandTransition),
    };
    if (c.at !== undefined) {
        p.approachType = c.at;
    }
    if (c.rw !== undefined) {
        p.runway = c.rw;
    }
    if (c.ma !== undefined) {
        p.missedApproach = expandMissedApproach(c.ma);
    }
    return p;
}
const dataPath = resolve(dirname(fileURLToPath(import.meta.url)), '../data/procedures.json.gz');
const raw = JSON.parse(gunzipSync(readFileSync(dataPath)).toString('utf-8'));
const records = raw.records.map(expandProcedure);
/**
 * Pre-processed snapshot of US instrument procedure data derived from
 * the FAA CIFP (Coded Instrument Flight Procedures) 28-day cycle.
 *
 * Contains Standard Instrument Departures (SIDs), Standard Terminal
 * Arrival Routes (STARs), and Instrument Approach Procedures (IAPs) in
 * the unified ARINC 424 leg model, including path terminators,
 * altitude and speed constraints, recommended navaids, RNP values, and
 * FAF / MAP / IAF / FACF flags.
 *
 * Pass the `records` array directly to `createProcedureResolver()` from
 * `@squawk/procedures` for zero-config lookups:
 *
 * ```typescript
 * import { usBundledProcedures } from '@squawk/procedure-data';
 * import { createProcedureResolver } from '@squawk/procedures';
 *
 * const resolver = createProcedureResolver({ data: usBundledProcedures.records });
 * ```
 */
export const usBundledProcedures = {
    properties: {
        generatedAt: raw.meta.generatedAt,
        cifpCycleDate: raw.meta.cifpCycleDate,
        recordCount: raw.meta.recordCount,
        sidCount: raw.meta.sidCount,
        starCount: raw.meta.starCount,
        iapCount: raw.meta.iapCount,
        legCount: raw.meta.legCount,
    },
    records,
};
