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

public class PerpustakaanMini {
    public static void main(String[] args) {
        Perpustakaan perpus = new Perpustakaan();
        perpus.tambahBuku("B-001", "Laskar Pelangi", 2);
        perpus.tambahBuku("B-002", "Bumi Manusia", 1);

        Anggota budi = perpus.daftar("Budi");
        Anggota siti = perpus.daftar("Siti");

        System.out.println(perpus.pinjam(budi, "B-001"));
        System.out.println(perpus.pinjam(siti, "B-001"));
        System.out.println(perpus.pinjam(siti, "B-002"));
        System.out.println(perpus.pinjam(siti, "B-002"));
        System.out.println(perpus.kembalikan(budi, "B-001"));
        System.out.println(perpus.pinjam(budi, "B-002"));
        System.out.println("Pinjaman Budi: " + budi.jumlahPinjaman()
                + ", pinjaman Siti: " + siti.jumlahPinjaman());
    }
}

class Buku {
    private final String kode;
    private final String judul;
    private int stok;

    Buku(String kode, String judul, int stok) {
        this.kode = kode;
        this.judul = judul;
        this.stok = stok;
    }

    String judul() {
        return judul;
    }

    boolean tersedia() {
        return stok > 0;
    }

    void kurangiStok() {
        stok--;
    }

    void tambahStok() {
        stok++;
    }
}

class Anggota {
    private final String nama;
    private final List<Buku> pinjaman = new ArrayList<>();

    Anggota(String nama) {
        this.nama = nama;
    }

    String nama() {
        return nama;
    }

    void catatPinjaman(Buku buku) {
        pinjaman.add(buku);
    }

    void hapusPinjaman(Buku buku) {
        pinjaman.remove(buku);
    }

    int jumlahPinjaman() {
        return pinjaman.size();
    }
}

// Mediator: menghubungkan Anggota dan Buku tanpa keduanya saling mengenal
class Perpustakaan {
    private final Map<String, Buku> katalog = new LinkedHashMap<>();
    private final Map<String, Anggota> anggota = new LinkedHashMap<>();

    void tambahBuku(String kode, String judul, int stok) {
        katalog.put(kode, new Buku(kode, judul, stok));
    }

    Anggota daftar(String nama) {
        return anggota.computeIfAbsent(nama, Anggota::new);
    }

    String pinjam(Anggota peminjam, String kode) {
        Buku buku = katalog.get(kode);
        if (buku == null) {
            return peminjam.nama() + " gagal: buku " + kode + " tidak ada";
        }
        if (!buku.tersedia()) {
            return peminjam.nama() + " gagal meminjam '" + buku.judul() + "': stok habis";
        }
        buku.kurangiStok();
        peminjam.catatPinjaman(buku);
        return peminjam.nama() + " meminjam '" + buku.judul() + "'";
    }

    String kembalikan(Anggota pengembali, String kode) {
        Buku buku = katalog.get(kode);
        if (buku == null || pengembali.jumlahPinjaman() == 0) {
            return pengembali.nama() + " gagal: tidak ada pinjaman " + kode;
        }
        buku.tambahStok();
        pengembali.hapusPinjaman(buku);
        return pengembali.nama() + " mengembalikan '" + buku.judul() + "'";
    }
}
