import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;

public class WadahSederhana {
    public static void main(String[] args) {
        Wadah wadah = new Wadah();
        wadah.daftar(KatalogFilm.class, KatalogMemori::new);
        wadah.daftar(LayananSewa.class,
                () -> new LayananSewa(wadah.ambil(KatalogFilm.class)));

        LayananSewa layanan = wadah.ambil(LayananSewa.class);
        layanan.sewa("Budi", "Laskar Pelangi");
        layanan.sewa("Siti", "Kelas 3 Cinta");
        System.out.println("Total film tersewa: " + layanan.jumlahFilm());
    }
}

// Container mini: registry tipe -> pabrik objek
class Wadah {
    private final Map<Class<?>, Supplier<?>> pabrik = new HashMap<>();

    <T> void daftar(Class<T> tipe, Supplier<T> pencipta) {
        pabrik.put(tipe, pencipta);
    }

    @SuppressWarnings("unchecked")
    <T> T ambil(Class<T> tipe) {
        Supplier<?> pencipta = pabrik.get(tipe);
        if (pencipta == null) {
            throw new IllegalStateException("Tidak terdaftar: " + tipe.getSimpleName());
        }
        return (T) pencipta.get();
    }
}

interface KatalogFilm {
    void catat(String judul);

    int jumlah();
}

class KatalogMemori implements KatalogFilm {
    private final List<String> film = new ArrayList<>();

    public void catat(String judul) {
        film.add(judul);
        System.out.println("[Katalog] " + judul + " tersewa");
    }

    public int jumlah() {
        return film.size();
    }
}

class LayananSewa {
    private final KatalogFilm katalog;

    LayananSewa(KatalogFilm katalog) {
        this.katalog = katalog;
    }

    void sewa(String pelanggan, String judul) {
        System.out.println(pelanggan + " menyewa " + judul);
        katalog.catat(judul);
    }

    int jumlahFilm() {
        return katalog.jumlah();
    }
}
