public class ValidasiPendaftaran {

    // Hasil validasi selalu eksplisit: diterima/tidak beserta alasannya.
    record Hasil(boolean diterima, String alasan) { }

    public static void main(String[] args) {
        System.out.println("=== Validasi nama pengguna (allowlist: a-z, 0-9, 3-16 karakter) ===");
        String[] kandidatNama = {
                "budi",
                "siti123",
                "ab",
                "budiwijayasetyawan12345",
                "Budi_Wijaya",
                "budi wijaya",
                "budi/../etc",
                "budi<script>",
                "budi;DROP",
                "budi\n",
                ""
        };
        for (String nama : kandidatNama) {
            Hasil hasil = validasiNamaPengguna(nama);
            laporkan("[" + nama.replace("\n", "\\n") + "]", hasil);
        }

        System.out.println();
        System.out.println("=== Validasi umur (parse-don't-validate + rentang 0-120) ===");
        String[] kandidatUmur = {"25", "0", "121", "-5", "25.5", "dua puluh", "2147483648"};
        for (String teks : kandidatUmur) {
            Hasil hasil = validasiUmur(teks);
            laporkan("[" + teks + "]", hasil);
        }
    }

    static void laporkan(String input, Hasil hasil) {
        System.out.printf("%-38s -> %s (%s)%n",
                input, hasil.diterima() ? "DITERIMA" : "DITOLAK  ", hasil.alasan());
    }

    // Allowlist: hanya kombinasi karakter yang diizinkan yang lolos.
    static Hasil validasiNamaPengguna(String nama) {
        if (nama == null) {
            return new Hasil(false, "nama tidak boleh kosong");
        }
        if (nama.length() < 3 || nama.length() > 16) {
            return new Hasil(false, "panjang harus 3-16 karakter, aktual " + nama.length());
        }
        if (!nama.matches("[a-z][a-z0-9]*")) {
            return new Hasil(false, "hanya huruf kecil a-z dan angka, diawali huruf");
        }
        return new Hasil(true, "memenuhi semua aturan");
    }

    // Parse, don't validate: ubah dulu ke tipe data yang tepat,
    // baru periksa rentang nilainya. Teks yang bukan bilangan ditolak mentah.
    static Hasil validasiUmur(String teks) {
        if (teks == null || teks.isBlank()) {
            return new Hasil(false, "umur tidak boleh kosong");
        }
        int umur;
        try {
            umur = Integer.parseInt(teks.trim());
        } catch (NumberFormatException e) {
            return new Hasil(false, "bukan bilangan bulat yang valid");
        }
        if (umur < 0 || umur > 120) {
            return new Hasil(false, "di luar rentang 0-120, aktual " + umur);
        }
        return new Hasil(true, "memenuhi semua aturan");
    }
}
