import java.util.List;
import java.util.Map;

/** Registri health check: agregasi status terburuk dan pemisahan liveness/readiness. */
public class PemeriksaKesehatan {

    /** Urutan deklarasi = urutan keparahan (worst-of memilih yang paling depan). */
    enum Status { DOWN, OUT_OF_SERVICE, UP, UNKNOWN }

    /** Satu pemeriksaan kesehatan: nama komponen, status, dan keterangan. */
    record Indikator(String nama, Status status, String keterangan) {}

    /** Pilih status paling parah dari kumpulan indikator. */
    static Status agregasi(List<Indikator> indikator) {
        Status terburuk = Status.UP;
        for (Indikator i : indikator) {
            if (i.status().ordinal() < terburuk.ordinal()) {
                terburuk = i.status();
            }
        }
        return terburuk;
    }

    /** Kode HTTP untuk laporan kesehatan keseluruhan. */
    static int httpStatus(Status s) {
        return (s == Status.UP) ? 200 : 503;
    }

    static String json(List<Indikator> indikator) {
        StringBuilder sb = new StringBuilder();
        sb.append("{\"status\":\"").append(agregasi(indikator)).append("\",\"indikator\":{");
        for (int i = 0; i < indikator.size(); i++) {
            Indikator in = indikator.get(i);
            if (i > 0) {
                sb.append(",");
            }
            sb.append("\"").append(in.nama()).append("\":\"").append(in.status()).append("\"");
        }
        sb.append("}}");
        return sb.toString();
    }

    static void laporan(String judul, List<Indikator> indikator) {
        System.out.println("== " + judul + " ==");
        for (Indikator i : indikator) {
            System.out.printf("  %-10s %-15s %s%n", i.nama(), i.status(), i.keterangan());
        }
        Status total = agregasi(indikator);
        System.out.println("  agregat    " + total + "  -> GET /health " + httpStatus(total)
                + " " + json(indikator));
        System.out.println();
    }

    public static void main(String[] args) {
        laporan("Skenario normal: seluruh komponen siap", List.of(
                new Indikator("database", Status.UP, "koneksi 20/20"),
                new Indikator("cache", Status.UP, "hit-ratio 96%"),
                new Indikator("disk", Status.UP, "sisa 41 GB")));

        laporan("Skenario database terganggu", List.of(
                new Indikator("database", Status.DOWN, "koneksi timeout"),
                new Indikator("cache", Status.UP, "hit-ratio 96%"),
                new Indikator("disk", Status.OUT_OF_SERVICE, "sisa 2 GB")));

        System.out.println("== Liveness vs readiness saat database terganggu ==");
        System.out.println("  GET /health/liveness   -> 200 {\"status\":\"UP\"}"
                + "   (proses masih hidup, jangan restart)");
        System.out.println("  GET /health/readiness  -> 503 {\"status\":\"DOWN\"}"
                + "   (tidak siap terima request, keluarkan dari rotasi)");
    }
}
