//! The comptime `compiler` library's name registry — the curated set of the
//! compiler's own functions reachable from comptime sx via
//! `abi(.zig) extern compiler`. See `current/PLAN-COMPILER-VM.md`.
//!
//! **This registry IS the safety boundary.** Only the names registered here are
//! bindable from user comptime code; a name not on the export list is rejected
//! at declaration (`weldedCompilerFn`). The comptime VM
//! (`comptime_vm.callCompilerFn`) services every welded call by name — this file
//! only carries the list of recognized names.
//!
//! **Direction note (2026-06-17 pivot).** The byte-weld of TYPES (sx structs whose
//! layout was validated to mirror the compiler's Zig records) was stripped — it
//! bolted a parallel layout regime + hand-marshaling onto a comptime value model
//! that isn't bytes. The replacement is a comptime VM where values are
//! native bytes, so the compiler-API needs no weld/validation/marshaling.

const std = @import("std");

/// The name of the only compiler library. A `fn abi(.zig) extern <lib>` with a
/// different `<lib>` is rejected — `compiler` is the sole comptime bind source.
pub const lib_name = "compiler";

// ── Functions (comptime-only, serviced by the comptime VM) ──────────────────

pub const BoundFn = struct {
    sx_name: []const u8,
};

/// The compiler-function export list. Every entry is serviced by name in
/// `comptime_vm.callCompilerFn`; `weldedCompilerFn` consults this list to decide
/// whether a `abi(.compiler)` name is a recognized compiler-API function.
pub const bound_fns = [_]BoundFn{
    .{ .sx_name = "intern" },
    .{ .sx_name = "text_of" },
    .{ .sx_name = "find_type" },
    .{ .sx_name = "type_field_count" },
    .{ .sx_name = "type_nominal_name" },
    .{ .sx_name = "type_field_name" },
    .{ .sx_name = "type_field_type" },
    .{ .sx_name = "type_kind" },
    .{ .sx_name = "type_field_value" },
    // ── write side (lowering-time, mints into the type table) ────────────────
    .{ .sx_name = "declare_type" },
    .{ .sx_name = "pointer_to" },
    .{ .sx_name = "register_type" },
    // ── BuildOptions (migrated off `#compiler` onto `abi(.compiler)`) ─────────
    .{ .sx_name = "build_options" },
    .{ .sx_name = "on_build" },
    // ── build-pipeline metadata queries (Phase 5.2) ──────────────────────────
    .{ .sx_name = "c_object_paths" },
    .{ .sx_name = "link_libraries" },
    .{ .sx_name = "emit_object" },
    .{ .sx_name = "link" },
    .{ .sx_name = "build_output" },
    .{ .sx_name = "build_target" },
    .{ .sx_name = "build_frameworks" },
    .{ .sx_name = "build_flags" },
    // ── BuildOptions accessors (Phase 5.5) ───────────────────────────────────
    .{ .sx_name = "add_link_flag" },
    .{ .sx_name = "add_framework" },
    .{ .sx_name = "set_output_path" },
    .{ .sx_name = "set_wasm_shell" },
    .{ .sx_name = "add_asset_dir" },
    .{ .sx_name = "asset_dir_count" },
    .{ .sx_name = "asset_dir_src_at" },
    .{ .sx_name = "asset_dir_dest_at" },
    .{ .sx_name = "set_post_link_module" },
    .{ .sx_name = "binary_path" },
    .{ .sx_name = "set_bundle_path" },
    .{ .sx_name = "set_bundle_id" },
    .{ .sx_name = "set_codesign_identity" },
    .{ .sx_name = "set_provisioning_profile" },
    .{ .sx_name = "bundle_path" },
    .{ .sx_name = "bundle_id" },
    .{ .sx_name = "codesign_identity" },
    .{ .sx_name = "provisioning_profile" },
    .{ .sx_name = "target_triple" },
    .{ .sx_name = "is_macos" },
    .{ .sx_name = "is_ios" },
    .{ .sx_name = "is_ios_device" },
    .{ .sx_name = "is_ios_simulator" },
    .{ .sx_name = "is_android" },
    .{ .sx_name = "framework_count" },
    .{ .sx_name = "framework_at" },
    .{ .sx_name = "framework_path_count" },
    .{ .sx_name = "framework_path_at" },
    .{ .sx_name = "set_manifest_path" },
    .{ .sx_name = "set_keystore_path" },
    .{ .sx_name = "manifest_path" },
    .{ .sx_name = "keystore_path" },
    .{ .sx_name = "jni_main_count" },
    .{ .sx_name = "jni_main_runtime_path_at" },
    .{ .sx_name = "jni_main_java_source_at" },
};

/// Look up a compiler function by its sx name. Returns null when the name is not
/// on the export list.
pub fn findFn(sx_name: []const u8) ?*const BoundFn {
    for (&bound_fns) |*bf| {
        if (std.mem.eql(u8, bf.sx_name, sx_name)) return bf;
    }
    return null;
}
