package tech.easyflow.agent.runtime.output;

import com.easyagents.agent.runtime.event.AgentRuntimeEvent;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import tech.easyflow.core.chat.protocol.ChatDomain;
import tech.easyflow.core.chat.protocol.ChatType;

/**
 * Agent 单次运行的协议无关输出边界。
 */
public interface AgentRunOutput {

    /**
     * 获取底层 SSE 连接。
     *
     * @return SSE Emitter
     */
    SseEmitter emitter();

    /**
     * 接收一条规范化运行时事件。
     *
     * @param event 运行时事件
     * @return 发送成功时为 true
     */
    boolean emitRuntimeEvent(AgentRuntimeEvent event);

    /**
     * 发送现有展示语义事件。
     *
     * @param domain 事件域
     * @param type 展示事件类型
     * @param payload 展示载荷
     * @return 发送成功时为 true
     */
    boolean emitViewEvent(ChatDomain domain, ChatType type, Object payload);

    /**
     * 判断当前协议输出是否已经收到可用于成功收口的运行时终态。
     *
     * <p>旧协议允许自然 EOF 兼容收口；要求显式终态的协议实现应覆盖此方法。</p>
     *
     * @return 可以按成功状态持久化并结束时为 true
     */
    default boolean canFinishSuccessfully() {
        return true;
    }

    /**
     * 判断浏览器 SSE 连接断开时是否应取消底层 Agent 运行。
     *
     * @return 连接断开需要取消运行时为 true
     */
    default boolean cancelRunOnDisconnect() {
        return true;
    }

    /**
     * 发送协议终态并关闭连接。
     *
     * @param finalText 服务端权威最终正文，可为空
     * @return 发送成功时为 true
     */
    boolean finish(String finalText);

    /**
     * 正常关闭连接。
     */
    void complete();

    /**
     * 以异常关闭连接。
     *
     * @param error 异常
     */
    void completeWithError(Throwable error);

    /**
     * 判断连接是否关闭。
     *
     * @return 已关闭时为 true
     */
    boolean isClosed();
}
