public class PetaKesalahan {

    static class ApiException extends RuntimeException {
        final int status;
        final String judul;

        ApiException(int status, String judul, String detail) {
            super(detail);
            this.status = status;
            this.judul = judul;
        }
    }

    static class TidakDitemukanException extends ApiException {
        TidakDitemukanException(String detail) {
            super(404, "Tidak ditemukan", detail);
        }
    }

    static class KonflikException extends ApiException {
        KonflikException(String detail) {
            super(409, "Konflik", detail);
        }
    }

    static class ValidasiException extends ApiException {
        ValidasiException(String detail) {
            super(400, "Validasi gagal", detail);
        }
    }

    record ProblemDetail(String tipe, String judul, int status, String detail, String instance) {

        String json() {
            return "{\"tipe\":\"" + tipe + "\",\"judul\":\"" + judul
                    + "\",\"status\":" + status
                    + ",\"detail\":\"" + detail
                    + "\",\"instance\":\"" + instance + "\"}";
        }
    }

    static String tangani(String instance, Runnable aksi) {
        try {
            aksi.run();
            return instance + " -> 200 OK (tanpa problem)";
        } catch (ApiException e) {
            ProblemDetail problem = new ProblemDetail(
                    "https://tokobudi.example/masalah/" + jenis(e.judul),
                    e.judul, e.status, e.getMessage(), instance);
            return instance + " -> " + problem.json();
        } catch (RuntimeException e) {
            System.out.println("[log server] RuntimeException tak terduga: "
                    + e.getClass().getSimpleName() + ": " + e.getMessage());
            ProblemDetail problem = new ProblemDetail(
                    "https://tokobudi.example/masalah/server",
                    "Kesalahan server internal", 500,
                    "Terjadi kesalahan internal. Silakan coba lagi nanti.", instance);
            return instance + " -> " + problem.json();
        }
    }

    static String jenis(String judul) {
        return judul.toLowerCase().replace(' ', '-');
    }

    public static void main(String[] args) {
        System.out.println(tangani("/produk/99",
                () -> { throw new TidakDitemukanException("produk 99 tidak ada"); }));
        System.out.println();
        System.out.println(tangani("/produk",
                () -> { throw new ValidasiException("field harga wajib positif"); }));
        System.out.println();
        System.out.println(tangani("/produk/3",
                () -> { throw new KonflikException("nama sudah dipakai produk lain"); }));
        System.out.println();
        System.out.println(tangani("/produk/5",
                () -> { throw new IllegalStateException("koneksi basis data terputus"); }));
        System.out.println();
        System.out.println(tangani("/produk/2", () -> { }));
    }
}
