import java.util.Random;

/**
 * Harness mini buatan tangan yang meniru kerangka JMH: fase pemanasan,
 * fase pengukuran berstatistik, dan lubang hitam (blackhole) pengonsumsi
 * hasil. "Derau" dimodelkan Random ber-seed sehingga output deterministik.
 */
public class HarnessMini {

    static long lubangHitam = 0;  // pengganti Blackhole JMH
    static int hasilTerpakai = 0; // pembukuan hasil agar terlihat hidup

    static int kerja(int i) {
        return (i * 37 + 11) % 1000;
    }

    // Satu iterasi benchmark: seluruh hasil dialirkan ke lubang hitam
    static long jalankanBatch(int jumlahOp) {
        long checksum = 0;
        for (int i = 0; i < jumlahOp; i++) {
            int r = kerja(i);
            lubangHitam += r;
            checksum += r;
            hasilTerpakai++;
        }
        return checksum;
    }

    // Derau penjadwalan tiruan: jumlah op nyata bergerak 97%-103% dari dasar
    static int opUntukIterasi(int dasar, Random derau) {
        int persen = 100 + derau.nextInt(7) - 3;
        return dasar * persen / 100;
    }

    public static void main(String[] args) {
        int iterasiPemanasan = 3;  // padanan @Warmup(iterations = 3)
        int iterasiUkur = 5;       // padanan @Measurement(iterations = 5)
        int opDasar = 10_000;
        Random derau = new Random(42);

        System.out.println("Konfigurasi : " + iterasiPemanasan + " iterasi pemanasan + "
            + iterasiUkur + " iterasi pengukuran, " + opDasar + " op dasar");

        // Fase 1: pemanasan. Pekerjaan tetap dikonsumsi, angka dibuang.
        long opPemanasan = 0;
        for (int w = 0; w < iterasiPemanasan; w++) {
            int op = opUntukIterasi(opDasar, derau);
            opPemanasan += op;
            jalankanBatch(op);
        }
        System.out.println("Pemanasan   : " + iterasiPemanasan + " iterasi, "
            + opPemanasan + " op dijalankan (tidak masuk laporan)");
        System.out.println("Pengukuran  :");

        // Fase 2: pengukuran dengan statistik
        int[] opPerIterasi = new int[iterasiUkur];
        for (int it = 0; it < iterasiUkur; it++) {
            opPerIterasi[it] = opUntukIterasi(opDasar, derau);
            long checksum = jalankanBatch(opPerIterasi[it]);
            System.out.println("  iterasi " + (it + 1) + " : " + opPerIterasi[it]
                + " op, checksum " + checksum);
        }

        int min = Integer.MAX_VALUE;
        int maks = Integer.MIN_VALUE;
        long total = 0;
        for (int op : opPerIterasi) {
            min = Math.min(min, op);
            maks = Math.max(maks, op);
            total += op;
        }
        double rerata = (double) total / iterasiUkur;
        double sebaran = 100.0 * (maks - min) / rerata;
        System.out.printf("Statistik   : rerata %.1f op, min %d, maks %d, sebaran %.2f%%%n",
            rerata, min, maks, sebaran);
        System.out.println("Blackhole   : " + hasilTerpakai + " hasil dikonsumsi dari "
            + hasilTerpakai + " pekerjaan (100%)");
    }
}
