package com.easyagents.agent.runtime.tool;

import com.easyagents.agent.runtime.AgentRuntimeContext;
import com.easyagents.agent.runtime.event.AgentRuntimeEvent;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Consumer;

/**
 * 传递给动态工具调用的上下文。
 */
public class AgentToolContext {

    private String requestId;
    private String traceId;
    private String sessionId;
    private String agentId;
    private String toolCallId;
    private AgentRuntimeContext runtimeContext = new AgentRuntimeContext();
    private Map<String, Object> metadata = new LinkedHashMap<>();
    private Consumer<AgentRuntimeEvent> eventEmitter;

    /**
     * 获取请求ID。
     *
     * @return 请求ID
     */
    public String getRequestId() {
        return requestId;
    }

    /**
     * 设置请求ID。
     *
     * @param requestId 请求ID
     */
    public void setRequestId(String requestId) {
        this.requestId = requestId;
    }

    /**
     * 获取链路ID。
     *
     * @return 链路ID
     */
    public String getTraceId() {
        return traceId;
    }

    /**
     * 设置链路ID。
     *
     * @param traceId 链路ID
     */
    public void setTraceId(String traceId) {
        this.traceId = traceId;
    }

    /**
     * 获取会话ID。
     *
     * @return 会话ID
     */
    public String getSessionId() {
        return sessionId;
    }

    /**
     * 设置会话ID。
     *
     * @param sessionId 会话ID
     */
    public void setSessionId(String sessionId) {
        this.sessionId = sessionId;
    }

    /**
     * 获取智能体ID。
     *
     * @return 智能体ID
     */
    public String getAgentId() {
        return agentId;
    }

    /**
     * 设置智能体ID。
     *
     * @param agentId 智能体ID
     */
    public void setAgentId(String agentId) {
        this.agentId = agentId;
    }

    /**
     * 获取工具调用ID。
     *
     * @return 工具调用ID
     */
    public String getToolCallId() {
        return toolCallId;
    }

    /**
     * 设置工具调用ID。
     *
     * @param toolCallId 工具调用ID
     */
    public void setToolCallId(String toolCallId) {
        this.toolCallId = toolCallId;
    }

    /**
     * 获取运行时上下文。
     *
     * @return 运行时上下文
     */
    public AgentRuntimeContext getRuntimeContext() {
        return runtimeContext;
    }

    /**
     * 设置运行时上下文。
     *
     * @param runtimeContext 运行时上下文
     */
    public void setRuntimeContext(AgentRuntimeContext runtimeContext) {
        this.runtimeContext = runtimeContext == null ? new AgentRuntimeContext() : runtimeContext;
    }

    /**
     * 获取元数据。
     *
     * @return 元数据
     */
    public Map<String, Object> getMetadata() {
        return metadata;
    }

    /**
     * 设置元数据。
     *
     * @param metadata 元数据
     */
    public void setMetadata(Map<String, Object> metadata) {
        this.metadata = metadata == null ? new LinkedHashMap<>() : metadata;
    }

    /**
     * 发射运行时旁路事件。
     *
     * <p>该方法主要供 runtime 包装层发射业务无关事件，例如异步工具生命周期事件。
     * 未配置事件发射器时静默忽略，避免非流式测试路径产生额外副作用。</p>
     *
     * @param event 运行时事件
     */
    public void emitEvent(AgentRuntimeEvent event) {
        if (eventEmitter != null && event != null) {
            eventEmitter.accept(event);
        }
    }

    /**
     * 获取运行时事件发射器。
     *
     * @return 运行时事件发射器
     */
    public Consumer<AgentRuntimeEvent> getEventEmitter() {
        return eventEmitter;
    }

    /**
     * 设置运行时事件发射器。
     *
     * @param eventEmitter 运行时事件发射器
     */
    public void setEventEmitter(Consumer<AgentRuntimeEvent> eventEmitter) {
        this.eventEmitter = eventEmitter;
    }
}
