/**
 * Load saved pipeline input sets and build runtime YAML for pipeline execute.
 * Used when callers pass input_set_ids without inline `inputs`, so execution
 * does not depend on Harness honoring `inputSetIdentifiers` query params alone.
 */
import YAML from "yaml";
import { HarnessApiError } from "./errors.js";
import { asRecord, asString } from "./type-guards.js";
function mergeVariableLists(a, b) {
    const byName = new Map();
    for (const v of a) {
        const n = asString(v.name);
        if (n)
            byName.set(n, { ...v });
    }
    for (const v of b) {
        const n = asString(v.name);
        if (n) {
            const prev = byName.get(n);
            byName.set(n, prev ? { ...prev, ...v } : { ...v });
        }
    }
    return [...byName.values()];
}
function getStageId(stageItem) {
    const o = asRecord(stageItem);
    const st = asRecord(o?.stage);
    return asString(st?.identifier);
}
function mergeStages(a, b) {
    const out = [...a];
    for (const nextItem of b) {
        const id = getStageId(nextItem);
        if (!id) {
            out.push(nextItem);
            continue;
        }
        const idx = out.findIndex((x) => getStageId(x) === id);
        if (idx < 0) {
            out.push(nextItem);
            continue;
        }
        const baseItem = asRecord(out[idx]);
        const nextRec = asRecord(nextItem);
        const baseStage = asRecord(baseItem?.stage);
        const nextStage = asRecord(nextRec?.stage);
        const mergedStage = { ...baseStage, ...nextStage };
        const baseVars = Array.isArray(baseStage?.variables)
            ? baseStage.variables.map((x) => asRecord(x)).filter((x) => !!x)
            : [];
        const nextVars = Array.isArray(nextStage?.variables)
            ? nextStage.variables.map((x) => asRecord(x)).filter((x) => !!x)
            : [];
        if (baseVars.length > 0 || nextVars.length > 0) {
            mergedStage.variables = mergeVariableLists(baseVars, nextVars);
        }
        out[idx] = { stage: mergedStage };
    }
    return out;
}
/** Merge two `pipeline` fragments from input sets (later ids override by variable / stage id). */
export function mergeRuntimePipelineFragments(base, next) {
    const out = { ...base, ...next };
    if (next.identifier !== undefined)
        out.identifier = next.identifier;
    const bv = Array.isArray(base.variables)
        ? base.variables.map((x) => asRecord(x)).filter((x) => !!x)
        : [];
    const nv = Array.isArray(next.variables)
        ? next.variables.map((x) => asRecord(x)).filter((x) => !!x)
        : [];
    if (nv.length > 0 || bv.length > 0) {
        out.variables = mergeVariableLists(bv, nv);
    }
    const bs = Array.isArray(base.stages) ? base.stages : [];
    const ns = Array.isArray(next.stages) ? next.stages : [];
    if (ns.length > 0 || bs.length > 0) {
        out.stages = mergeStages(bs, ns);
    }
    return out;
}
async function fetchInputSetPipelineFragment(client, pipelineId, orgId, projectId, inputSetId) {
    const raw = await client.request({
        method: "GET",
        path: `/pipeline/api/inputSets/${encodeURIComponent(inputSetId)}`,
        params: {
            orgIdentifier: orgId,
            projectIdentifier: projectId,
            pipelineIdentifier: pipelineId,
        },
    });
    const r = asRecord(raw);
    const st = asString(r?.status);
    if (st === "ERROR" || st === "FAILURE") {
        const msg = asString(r?.message) ?? "Input set GET returned ERROR";
        throw new HarnessApiError(msg, 400, asString(r?.code), asString(r?.correlationId));
    }
    const entity = asRecord(r?.data) ?? r;
    const yamlStr = asString(entity?.inputSetYaml);
    if (!yamlStr)
        return undefined;
    const doc = YAML.parse(yamlStr);
    const root = asRecord(doc);
    const inputSet = asRecord(root?.inputSet) ?? root;
    const pipeline = asRecord(inputSet?.pipeline);
    return pipeline ?? undefined;
}
/**
 * Returns YAML string `{ pipeline: ... }` suitable for pipeline execute body,
 * or undefined if no ids.
 */
export async function materializeInputSetsToRuntimeYaml(client, params) {
    if (params.inputSetIds.length === 0)
        return undefined;
    let merged;
    for (const id of params.inputSetIds) {
        const fragment = await fetchInputSetPipelineFragment(client, params.pipelineId, params.orgId, params.projectId, id);
        if (!fragment) {
            throw new HarnessApiError(`Input set "${id}" not found or has no pipeline fragment for pipeline "${params.pipelineId}".`, 404);
        }
        merged = merged ? mergeRuntimePipelineFragments(merged, fragment) : fragment;
    }
    return YAML.stringify({ pipeline: merged });
}
//# sourceMappingURL=materialize-input-sets.js.map