import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class TabelAutoconfig {

    // Satu kandidat auto-configuration dengan syarat @ConditionalOnClass
    // dan (opsional) syarat @ConditionalOnProperty.
    record Kandidat(String nama, String kelasWajib, String propertiWajib, String efek) { }

    private static final List<Kandidat> KANDIDAT = List.of(
            new Kandidat("DataSourceAutoConfiguration",
                    "javax.sql.DataSource", "spring.datasource.url",
                    "pool koneksi HikariCP dibuat"),
            new Kandidat("WebMvcAutoConfiguration",
                    "org.springframework.web.servlet.DispatcherServlet", null,
                    "infrastruktur MVC + Jackson terpasang"),
            new Kandidat("JpaRepositoriesAutoConfiguration",
                    "jakarta.persistence.EntityManager", null,
                    "infrastruktur Spring Data JPA aktif"),
            new Kandidat("RedisAutoConfiguration",
                    "org.springframework.data.redis.RedisConnection", null,
                    "cache Redis"),
            new Kandidat("TaskSchedulingAutoConfiguration",
                    "org.springframework.scheduling.TaskScheduler", "spring.task.scheduling.pool.size",
                    "executor @Scheduled dikonfigurasi"));

    public static void main(String[] args) {
        // Simulasi classpath hasil starter web + data-jpa + scheduling.
        Set<String> kelasDiClasspath = Set.of(
                "javax.sql.DataSource",
                "org.springframework.web.servlet.DispatcherServlet",
                "jakarta.persistence.EntityManager",
                "org.springframework.scheduling.TaskScheduler");

        // Simulasi application.properties yang ditulis pengembang.
        Map<String, String> properti = new LinkedHashMap<>();
        properti.put("spring.datasource.url", "jdbc:h2:mem:demo");
        properti.put("spring.task.scheduling.pool.size", "4");

        System.out.println("Kelas kunci di classpath : " + kelasDiClasspath.size());
        System.out.println("Properti pengembang      : " + properti.keySet());
        System.out.println();

        int aktif = 0;
        for (Kandidat k : KANDIDAT) {
            boolean kelasOk = kelasDiClasspath.contains(k.kelasWajib());
            boolean propOk = k.propertiWajib() == null
                    || properti.containsKey(k.propertiWajib());
            boolean cocok = kelasOk && propOk;
            if (cocok) {
                aktif++;
            }
            System.out.println((cocok ? "MATCH " : "LEWAT ") + k.nama());
            System.out.println("       syarat kelas    : " + k.kelasWajib()
                    + " -> " + (kelasOk ? "ada" : "tidak ada"));
            if (k.propertiWajib() != null) {
                System.out.println("       syarat properti : " + k.propertiWajib()
                        + " -> " + (propOk ? "terisi" : "kosong"));
            }
            System.out.println("       hasil           : "
                    + (cocok ? k.efek() : "konfigurasi dilewati"));
            System.out.println();
        }
        System.out.println("Total aktif: " + aktif + " dari " + KANDIDAT.size() + " kandidat");
    }
}
