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

public class Main {
    record Order(String id, long totalCents) {
        Order {
            if (id == null || id.isBlank() || totalCents < 0)
                throw new IllegalArgumentException("Invalid order");
        }
    }
    interface OrderWriter { void save(Order order); }
    interface Discount { long apply(long cents); }
    static final class InMemoryOrders implements OrderWriter {
        final List<Order> values = new ArrayList<>();
        public void save(Order order) { values.add(order); }
    }
    static final class Checkout {
        private final OrderWriter orders;
        private final Discount discount;
        Checkout(OrderWriter orders, Discount discount) {
            this.orders = orders;
            this.discount = discount;
        }
        Order place(String id, long cents) {
            if (cents < 0) throw new IllegalArgumentException("Negative total");
            long discounted = discount.apply(cents);
            if (discounted < 0 || discounted > cents)
                throw new IllegalArgumentException("Discount violated its contract");
            Order order = new Order(id, discounted);
            orders.save(order);
            return order;
        }
    }
    public static void main(String[] args) {
        InMemoryOrders orders = new InMemoryOrders();
        Checkout standard = new Checkout(orders, cents -> cents);
        Checkout promotion = new Checkout(orders, cents -> cents - cents / 10);
        if (standard.place("a", 1000).totalCents() != 1000) throw new AssertionError();
        if (promotion.place("b", 1000).totalCents() != 900) throw new AssertionError();
        try {
            new Checkout(orders, cents -> -1).place("invalid", 1000);
            throw new AssertionError("Invalid discount was accepted");
        } catch (IllegalArgumentException expected) { /* Contract enforced. */ }
        if (orders.values.size() != 2) throw new AssertionError();
        System.out.println("OK: policies replaced; invalid order not saved");
    }
}
