import java.util.concurrent.*;

public class ScopedStructuredDemo {
    static final ScopedValue<String> USER = ScopedValue.newInstance();

    static String current() {
        return USER.isBound() ? USER.get() : "<unbound>";
    }

    public static void main(String[] args) throws Exception {
        ScopedValue.where(USER, "alice").run(() -> {
            try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
                var inherited = scope.fork(ScopedStructuredDemo::current);
                scope.join().throwIfFailed();
                System.out.println("structured subtask=" + inherited.get());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

            try {
                Thread manual = Thread.ofVirtual().start(
                        () -> System.out.println("manual virtual thread=" + current()));
                manual.join();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });

        String outside = ScopedValue.where(USER, "bob").call(
                () -> "call returns " + USER.get());
        System.out.println(outside);
    }
}
