import java.nio.file.Path;

public class PenjagaPath {

    // Semua akses berkas pengguna dibatasi di bawah direktori ini.
    private static final Path BASIS = Path.of("data");

    // Hasil pemeriksaan: diterima atau ditolak beserta keterangannya.
    record Hasil(boolean diterima, String keterangan) { }

    public static void main(String[] args) {
        String[] masukan = {
                "teks.txt",
                "laporan/penjualan.csv",
                "laporan/../catatan.txt",
                "../etc/passwd",
                "laporan/../../etc/passwd",
                "..\\..\\windows\\system32",
                "/etc/passwd"
        };

        System.out.println("=== Validator path dengan basis: " + BASIS + " ===");
        for (String m : masukan) {
            laporkan(m, periksa(m));
        }
    }

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

    // Tiga lapis: tolak karakter berisiko, jabarkan terhadap basis,
    // normalisasi, lalu pastikan hasil tetap di dalam basis.
    static Hasil periksa(String masukan) {
        if (masukan == null || masukan.isBlank()) {
            return new Hasil(false, "masukan kosong");
        }
        if (masukan.contains("\\") || masukan.contains("\0")) {
            return new Hasil(false, "karakter pemisah atau NUL tidak diizinkan");
        }
        Path dijabarkan = BASIS.resolve(masukan).normalize();
        if (!dijabarkan.startsWith(BASIS)) {
            return new Hasil(false, "keluar dari basis, terjabar menjadi " + dijabarkan);
        }
        return new Hasil(true, "jalur aman: " + dijabarkan);
    }
}
