import java.util.Comparator;
import java.util.PriorityQueue;

public class UjiAntrean {

    static int lulus = 0;
    static int gagal = 0;

    // Triase IGD: P1 paling prioritas, disusul P2, lalu P3.
    enum LevelTriage { P1, P2, P3 }

    record Pasien(String nama, LevelTriage level, int nomorKedatangan) { }

    static void periksa(String namaUji, boolean kondisi) {
        if (kondisi) {
            lulus++;
            System.out.println("LULUS  : " + namaUji);
        } else {
            gagal++;
            System.out.println("GAGAL  : " + namaUji);
        }
    }

    static PriorityQueue<Pasien> antreanBaru() {
        Comparator<Pasien> urutan = Comparator
                .comparing((Pasien p) -> p.level())
                .thenComparingInt(Pasien::nomorKedatangan);
        return new PriorityQueue<>(urutan);
    }

    public static void main(String[] args) {
        // Uji 1: level triage menentukan urutan, bukan urutan kedatangan.
        PriorityQueue<Pasien> antrean = antreanBaru();
        antrean.add(new Pasien("Siti", LevelTriage.P3, 1));
        antrean.add(new Pasien("Budi", LevelTriage.P2, 2));
        antrean.add(new Pasien("Dewi", LevelTriage.P1, 3));

        periksa("Pasien P1 dilayani lebih dulu",
                antrean.poll().equals(new Pasien("Dewi", LevelTriage.P1, 3)));
        periksa("Pasien P2 menyusul",
                antrean.poll().equals(new Pasien("Budi", LevelTriage.P2, 2)));
        periksa("Pasien P3 terakhir",
                antrean.poll().equals(new Pasien("Siti", LevelTriage.P3, 1)));
        periksa("Antrean kosong setelah semua dilayani", antrean.isEmpty());

        // Uji 2: level sama berarti yang datang lebih dulu menang (FIFO).
        PriorityQueue<Pasien> selevel = antreanBaru();
        selevel.add(new Pasien("Joko", LevelTriage.P2, 4));
        selevel.add(new Pasien("Budi", LevelTriage.P2, 2));

        periksa("Antrean FIFO untuk level yang sama",
                selevel.poll().nama().equals("Budi"));

        // Uji 3: record Pasien memiliki value semantics.
        Pasien a = new Pasien("Dewi", LevelTriage.P1, 3);
        Pasien b = new Pasien("Dewi", LevelTriage.P1, 3);
        periksa("Record dengan data sama dianggap sama", a.equals(b));
        periksa("hashCode juga sama", a.hashCode() == b.hashCode());

        // Uji 4: nilai field record tidak bisa berubah lewat referensi bersama.
        Pasien asli = new Pasien("Rani", LevelTriage.P1, 5);
        Pasien salinan = asli; // dua nama menunjuk objek yang sama
        periksa("Referensi yang sama tetap objek yang sama", salinan == asli);

        System.out.println();
        System.out.println("Ringkasan: " + lulus + " lulus, " + gagal + " gagal");
    }
}
