import java.util.ArrayList;
import java.util.List;

/** Satu alur bisnis yang sama, dijalankan pada dua gaya arsitektur berbeda. */
public class DuaGayaArsitektur {
    /** Satu langkah eksekusi: siapa pelakunya, apa aksinya, lintas jaringan atau tidak. */
    record Langkah(String pelaku, String aksi, boolean lintasJaringan) {}

    public static void main(String[] args) {
        System.out.println("== MONOLITH: satu proses, satu unit deployable ==");
        List<Langkah> mono = jalurMonolith();
        cetak(mono);

        System.out.println();
        System.out.println("== MICROSERVICES: empat proses, empat unit deployable ==");
        List<Langkah> mikro = jalurMicroservices();
        cetak(mikro);

        System.out.println();
        System.out.println("== PERBANDINGAN ==");
        System.out.println("unit deploy       : monolith=1, microservices=4");
        System.out.println("lompatan jaringan : monolith=" + hitungJaringan(mono)
                + ", microservices=" + hitungJaringan(mikro));
        System.out.println("dampak bila modul Inventori berhenti:");
        System.out.println("  monolith      = seluruh proses ikut berhenti");
        System.out.println("  microservices = 3 service lain tetap hidup");
    }

    static void cetak(List<Langkah> langkah) {
        for (Langkah l : langkah) {
            String media = l.lintasJaringan() ? "jaringan" : "method";
            System.out.println("  [" + l.pelaku() + "] " + l.aksi() + "  (" + media + ")");
        }
    }

    static int hitungJaringan(List<Langkah> langkah) {
        int total = 0;
        for (Langkah l : langkah) {
            if (l.lintasJaringan()) {
                total++;
            }
        }
        return total;
    }

    /** Pada monolith, empat modul tinggal dalam satu proses: cukup panggilan method. */
    static List<Langkah> jalurMonolith() {
        List<Langkah> jejak = new ArrayList<>();
        jejak.add(new Langkah("proses Aplikasi", "Order.catat(pesanan-1001)", false));
        jejak.add(new Langkah("proses Aplikasi", "Inventori.kurangiStok(pesanan-1001)", false));
        jejak.add(new Langkah("proses Aplikasi", "Pembayaran.tagih(pesanan-1001)", false));
        jejak.add(new Langkah("proses Aplikasi", "Notifikasi.kirim(pesanan-1001)", false));
        return jejak;
    }

    /** Pada microservices, tiap modul jadi service dengan alamat sendiri. */
    static List<Langkah> jalurMicroservices() {
        List<Langkah> jejak = new ArrayList<>();
        jejak.add(new Langkah("klien              ", "POST order/api/pesanan", true));
        jejak.add(new Langkah("svc order      :8081", "catat pesanan-1001", false));
        jejak.add(new Langkah("svc order      :8081", "GET inventori/api/stok", true));
        jejak.add(new Langkah("svc inventori  :8082", "kurangiStok pesanan-1001", false));
        jejak.add(new Langkah("svc order      :8081", "POST pembayaran/api/tagih", true));
        jejak.add(new Langkah("svc pembayaran :8083", "tagih pesanan-1001", false));
        jejak.add(new Langkah("svc order      :8081", "POST notifikasi/api/kirim", true));
        jejak.add(new Langkah("svc notifikasi :8084", "kirim pesanan-1001", false));
        return jejak;
    }
}
