package com.lingniu.ingest.core.pipeline;

import com.lingniu.ingest.api.event.VehicleEvent;
import com.lingniu.ingest.api.pipeline.IngestContext;
import com.lingniu.ingest.api.pipeline.IngestInterceptor;
import com.lingniu.ingest.api.pipeline.RawFrame;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;

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

/**
 * 顺序执行的拦截器链，通过 Spring {@code @Order} 或 {@code Ordered} 排序。
 *
 * <p>{@link #before(RawFrame, IngestContext)} 是接入链路的准入闸门：任何拦截器返回
 * {@code false} 或调用 {@link IngestContext#abort(String)} 都会停止后续协议解析/Handler 调用。
 * {@link #after(VehicleEvent, IngestContext)} 与 {@link #onError(Throwable, IngestContext)}
 * 则保持广播语义，让指标、审计等横切逻辑都能观察到同一条处理结果。
 */
public final class InterceptorChain {

    private final List<IngestInterceptor> interceptors;

    public InterceptorChain(List<IngestInterceptor> interceptors) {
        List<IngestInterceptor> sorted = new ArrayList<>(interceptors);
        AnnotationAwareOrderComparator.sort(sorted);
        this.interceptors = List.copyOf(sorted);
    }

    public boolean before(RawFrame frame, IngestContext ctx) {
        for (IngestInterceptor i : interceptors) {
            // before 阶段短路是有意的：去重、限流失败后不应继续消耗解析和存储资源。
            if (!i.before(frame, ctx) || ctx.aborted()) {
                return false;
            }
        }
        return true;
    }

    public void after(VehicleEvent event, IngestContext ctx) {
        for (IngestInterceptor i : interceptors) {
            i.after(event, ctx);
        }
    }

    public void onError(Throwable error, IngestContext ctx) {
        for (IngestInterceptor i : interceptors) {
            i.onError(error, ctx);
        }
    }
}
