// Exercise 2: exception chaining and try-with-resources
//
// Part A: implement wrapAndRethrow so that when `riskyOperation()` throws,
// the original exception is preserved as the CAUSE of a new
// ProcessingException (do not swallow it).
//
// Part B: implement CountingResource (an AutoCloseable) so that closing it
// appends "closed" to the shared log, and use it with try-with-resources
// inside runWithResource so the log shows resources closed in REVERSE
// declaration order automatically.

import java.util.ArrayList;
import java.util.List;

public class java_exception_handling_exercise_2 {

    static class ProcessingException extends RuntimeException {
        ProcessingException(String message, Throwable cause) {
            super(message, cause);
        }
    }

    static void riskyOperation() {
        throw new IllegalStateException("underlying failure");
    }

    static void wrapAndRethrow() {
        // TODO: call riskyOperation() inside a try; catch its exception and
        // rethrow a new ProcessingException("wrapped", e) — passing the
        // caught exception `e` as the cause, not discarding it
    }

    static class CountingResource implements AutoCloseable {
        final String name;
        final List<String> log;

        CountingResource(String name, List<String> log) {
            this.name = name;
            this.log = log;
        }

        @Override
        public void close() {
            // TODO: append name to log
        }
    }

    static List<String> runWithResources() {
        List<String> log = new ArrayList<>();
        // TODO: use try-with-resources to open CountingResource("first", log)
        // and CountingResource("second", log), doing nothing else in the body.
        // They should close in REVERSE order: "second" then "first".
        return log;
    }

    // --- self-check: do not modify below this line ---
    public static void main(String[] args) {
        boolean ok = true;

        try {
            wrapAndRethrow();
            ok = false; // should have thrown
        } catch (ProcessingException e) {
            ok &= e.getMessage().equals("wrapped");
            ok &= e.getCause() != null;
            ok &= e.getCause() instanceof IllegalStateException;
            ok &= e.getCause().getMessage().equals("underlying failure");
        }

        List<String> log = runWithResources();
        ok &= log.equals(List.of("second", "first"));

        System.out.println(ok ? "PASS" : "FAIL");
    }
}
