package com.bookshop.behavioral.chainofresponsibility;

import java.util.List;

/**
 * A handler in the chain: performs its own check and, if satisfied, passes the
 * request to the next handler. The chain itself is assembled with {@link #chainOf}.
 */
public abstract class OrderCheck {

    private OrderCheck next;

    /**
     * Links the given checks in order and returns the head of the chain.
     *
     * <p>Linking stores each handler's successor in the handler itself, so a handler
     * instance belongs to <em>one</em> chain at a time -- to assemble several pipelines
     * from the same parts, build each from fresh instances. Relinking the same
     * instances into a new chain is safe: every {@code next} is overwritten, including
     * the last handler's, so no tail from a previous, longer chain survives.
     */
    public static OrderCheck chainOf(List<OrderCheck> checks) {
        if (checks.isEmpty()) {
            throw new IllegalArgumentException("chain needs at least one check");
        }
        for (int i = 0; i < checks.size() - 1; i++) {
            checks.get(i).next = checks.get(i + 1);
        }
        checks.get(checks.size() - 1).next = null;
        return checks.get(0);
    }

    public final ValidationResult validate(OrderRequest request) {
        ValidationResult result = check(request);
        if (!result.valid() || next == null) {
            return result;
        }
        return next.validate(request);
    }

    protected abstract ValidationResult check(OrderRequest request);
}
