package LLD.vendingmachine;

import java.util.HashMap;
import java.util.Map;

public class VendingMachineSystem {

class Product { String code; String name; double price; int quantity; Product(String code, String name, double price, int quantity) { this.code = code; this.name = name; this.price = price; this.quantity = quantity; } } interface VendingState { void select(VendingMachine machine, String code); void insert(VendingMachine machine, double amount); void dispense(VendingMachine machine); void cancel(VendingMachine machine); } class IdleState implements VendingState { @Override public void select(VendingMachine machine, String code) { Product product = machine.products.get(code); if (product == null || product.quantity == 0) { throw new IllegalStateException("Product unavailable"); } machine.selected = product; machine.state = new SelectedState(); } @Override public void insert(VendingMachine machine, double amount) { throw new IllegalStateException("Select Product first"); } @Override public void dispense(VendingMachine machine) { throw new IllegalStateException("Select Product first"); } @Override public void cancel(VendingMachine machine) { throw new IllegalStateException("No transaction"); } } class SelectedState implements VendingState { @Override public void select(VendingMachine machine, String code) { throw new IllegalStateException("Product already selected"); } @Override public void insert(VendingMachine machine, double amount) { machine.money += amount; if (machine.money >= machine.selected.price) { machine.state = new DispensingState(); } } @Override public void dispense(VendingMachine machine) { throw new IllegalStateException("Insufficient money"); } @Override public void cancel(VendingMachine machine) { System.out.println("Transaction cancelled. Returning: $" + machine.money); machine.reset(); } } class DispensingState implements VendingState { @Override public void select(VendingMachine machine, String code) { throw new IllegalStateException("Transaction in progress"); } @Override public void insert(VendingMachine machine, double amount) { throw new IllegalStateException("Payment complete"); } @Override public void dispense(VendingMachine machine) { machine.selected.quantity--; double change = machine.money - machine.selected.price; System.out.println("Dispensing " + machine.selected.name); System.out.println("Change: $" + change); machine.reset(); } @Override public void cancel(VendingMachine machine) { System.out.println("Too late to cancel, dispensing in progress."); machine.reset(); } } class VendingMachine { Map<String, Product> products = new HashMap<>(); VendingState state = new IdleState(); Product selected; double money; void select(String code) { state.select(this, code); } void insert(double amount) { state.insert(this, amount); } void dispense() { state.dispense(this); } void cancel() { state.cancel(this); } void reset() { selected = null; money = 0; state = new IdleState(); } } public static void main(String[] args) { // 1. Initialize the system VendingMachineSystem system = new VendingMachineSystem(); VendingMachine machine = system.new VendingMachine(); // 2. Load products into the machine machine.products.put("A1", system.new Product("A1", "Coke", 1.50, 5)); machine.products.put("B2", system.new Product("B2", "Chips", 2.00, 3)); machine.products.put("C3", system.new Product("C3", "Water", 1.00, 0)); // Out of stock System.out.println("Vending Machine Setup Complete.\n"); try { // Test Case 1: Successful Purchase with Exact Change System.out.println("--- Test 1: Buying Chips ---"); machine.select("B2"); System.out.println("Selected Chips. Price: $2.00"); machine.insert(2.00); machine.dispense(); // Test Case 2: Successful Purchase with Overpayment System.out.println("\n--- Test 2: Buying Coke (with extra money) ---"); machine.select("A1"); System.out.println("Selected Coke. Price: $1.50"); machine.insert(1.00); machine.insert(1.00); // Total $2.00, triggers DispensingState machine.dispense(); // Should return $0.50 change // Test Case 3: Cancelling a transaction System.out.println("\n--- Test 3: Cancelling Transaction ---"); machine.select("A1"); System.out.println("Selected Coke. Price: $1.50"); machine.insert(1.00); machine.cancel(); // Test Case 4: Trying to buy out of stock item System.out.println("\n--- Test 4: Buying Out of Stock Item ---"); machine.select("C3"); // Should throw an exception } catch (Exception e) { System.out.println("Error: " + e.getMessage()); } } 

}