// Phase 1 step 1.6 (PLAN-FFI.md): non-void return shapes through
// `#objc_call`. Each return type triggers a distinct LLVMBuildCall2
// function-type combination so emit_llvm's per-call-site lowering
// has to pick the right ABI per call.
//
// We exercise both nil-recv (libobjc guarantees zero result for
// every shape) and real-recv paths so the ABI is verified beyond
// "the runtime no-oped the call."

#import "modules/std.sx";
#import "modules/compiler.sx";
#import "modules/std/objc.sx";

main :: () -> s32 {
    inline if OS == .macos {
        // ── Nil-recv quick smoke ───────────────────────────────────
        nil_cls := #objc_call(*void)(null, "class");
        print("nil class    = {}\n", nil_cls == null);

        nil_n := #objc_call(s64)(null, "hash");
        print("nil hash     = {}\n", nil_n);

        // ── Real-recv: NSObject ────────────────────────────────────
        // *void return: [NSObject class] -> NSObject's metaclass (non-null,
        // and conveniently == self when sent to the class itself).
        ns_object := objc_getClass("NSObject".ptr);
        meta := #objc_call(*void)(ns_object, "class");
        print("meta non-null = {}\n", meta != null);

        // s64 return: [obj hash] returns NSUInteger. On the NSObject
        // class itself the value is implementation-defined but stable
        // within a process — pinning it as non-zero is enough for ABI
        // verification.
        h := #objc_call(s64)(ns_object, "hash");
        print("hash non-zero = {}\n", h != 0);
    }
    inline if OS != .macos {
        print("skipped (not macos)\n");
    }
    0;
}
