package com.seer.teach.teacher.processor.base;

import reactor.core.Disposable;
import reactor.core.publisher.Flux;

/**
 * 抽象流处理器类，用于处理基于Reactor的流式数据处理
 * 该类定义了流处理的完整生命周期，包括开始、数据处理、错误处理、完成等各个阶段
 *
 * @param <Req> 请求参数类型
 * @param <Resp> 响应数据类型
 * @param <GlobalParam> 全局参数类型
 */
public abstract class AbstractStreamProcessor<Req, Resp, GlobalParam> implements StreamProcessor<Req, Resp, GlobalParam> {

    /**
     * 处理流数据的主要方法，定义了完整的流处理生命周期
     * 该方法会按顺序注册各种事件处理器，并启动流的订阅
     *
     * @param userId 用户ID
     * @param req 请求参数对象
     * @param device 设备信息
     * @param flux 响应数据流
     * @param param 全局参数对象
     */
    @Override
    public void process(Integer userId,
                        Req req,
                        String device,
                        Flux<Resp> flux,
                        GlobalParam globalParam) {
        Disposable disposable = flux
                .doFirst(() -> onBeforeStart(userId, req,device,flux, globalParam))
                .doOnSubscribe(sub -> onStart(userId, req, globalParam))
                .doOnNext(resp -> onData(userId, device, resp, globalParam))
                .doOnError(error -> onError(userId, device, globalParam, error))
                .doOnComplete(() -> onComplete(userId, req, device, globalParam))
                .doFinally(signalType -> onFinal(userId, req, device, globalParam))
                .subscribe();

        onRegister(userId, disposable);
    }

    /**
     * 流开始前的回调方法，在流处理启动之前执行
     *
     * @param userId 用户ID
     * @param req 请求参数对象
     * @param device 设备信息
     * @param flux 响应数据流
     * @param param 全局参数对象
     */
    protected abstract void onBeforeStart(Integer userId, Req req, String device, Flux<Resp> flux, GlobalParam param);

    /**
     * 流订阅开始时的回调方法，当有订阅者订阅流时执行
     *
     * @param userId 用户ID
     * @param req 请求参数对象
     * @param param 全局参数对象
     */
    protected abstract void onStart(Integer userId, Req req, GlobalParam param);

    /**
     * 接收到流数据时的回调方法，每产生一个数据项时执行
     *
     * @param userId 用户ID
     * @param device 设备信息
     * @param data 响应数据项
     * @param param 全局参数对象
     */
    protected abstract void onData(Integer userId, String device, Resp data, GlobalParam param);

    /**
     * 流处理发生错误时的回调方法
     *
     * @param userId 用户ID
     * @param device 设备信息
     * @param param 全局参数对象
     * @param error 错误信息
     */
    protected abstract void onError(Integer userId, String device, GlobalParam param, Throwable error);

    /**
     * 流处理完成时的回调方法，当流正常结束时执行
     *
     * @param userId 用户ID
     * @param req 请求参数对象
     * @param device 设备信息
     * @param param 全局参数对象
     */
    protected void onComplete(Integer userId, Req req, String device, GlobalParam param) {
    }

    /**
     * 流处理最终回调方法，无论流正常完成还是异常结束都会执行
     *
     * @param userId 用户ID
     * @param req 请求参数对象
     * @param device 设备信息
     * @param param 全局参数对象
     */
    private void onFinal(Integer userId, Req req, String device, GlobalParam param) {
    }

    /**
     * 注册Disposable的回调方法，用于管理流的生命周期
     *
     * @param userId 用户ID
     * @param disposable 可释放资源对象，用于取消流处理
     */
    protected abstract void onRegister(Integer userId, Disposable disposable);


}

