public class NilaiTerlingkup {

    // Nilai terlingkup: immutable, terikat sementara oleh scope.
    static final ScopedValue<String> PENGGUNA = ScopedValue.newInstance();
    static final ScopedValue<Integer> KUOTA = ScopedValue.newInstance();

    static void cetakLaporan() {
        System.out.printf("pengguna=%s, kuota=%d%n", PENGGUNA.get(), KUOTA.get());
    }

    public static void main(String[] args) throws InterruptedException {
        // Satu scope mengikat beberapa nilai sekaligus lewat rantai where.
        ScopedValue.where(PENGGUNA, "budi").where(KUOTA, 100).run(() -> {
            cetakLaporan();

            // Rebinding di scope bersarang hanya berlaku di dalamnya.
            ScopedValue.where(PENGGUNA, "siti").run(NilaiTerlingkup::cetakLaporan);
            cetakLaporan(); // kembali ke "budi"
        });

        // Setelah scope berakhir, nilai tidak lagi terikat.
        System.out.println("setelah scope : " + PENGGUNA.isBound());

        // Thread biasa TIDAK mewarisi binding; pewarisan hanya terjadi
        // lewat structured concurrency pada scope yang sama.
        ScopedValue.where(PENGGUNA, "dewi").run(() -> {
            Thread anak = Thread.ofVirtual().start(() ->
                    System.out.println("anak lihat    : " + PENGGUNA.isBound()));
            try {
                anak.join();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        // get() tanpa binding gagal cepat dengan exception yang jelas.
        try {
            PENGGUNA.get();
        } catch (RuntimeException e) {
            System.out.println("tanpa binding : " + e.getClass().getSimpleName());
        }
    }
}
