package com.gzzm.lobster.sandbox;

import com.gzzm.lobster.identity.UserContext;
import com.gzzm.lobster.thread.ThreadRoom;

import java.util.Collections;
import java.util.List;

/**
 * SandboxRequest —— 一次 code_exec 的入参.
 */
public final class SandboxRequest {

    private final ThreadRoom thread;
    private final UserContext user;
    private final String runId;
    private final String toolCallId;
    /** "python" / "javascript"，已规范化成小写；决定容器里入口命令 */
    private final String language;
    /** LLM 生成的代码（inline；已通过长度校验）. code 和 codeRef 二选一，优先 code. */
    private final String code;
    /**
     * 代码引用（workspace ref：artId / resId / oaId）—— LLM 用 write_file 把长脚本写成
     * Artifact 后，通过 codeRef 触发 code_exec，避免把几十 KB 脚本塞进 tool_call 参数.
     * 与 code 互斥；若提供，SandboxService 解析其内容作为脚本.
     */
    private final String codeRef;
    /** 要挂到 /inputs 的 workspace ref 列表（resId / artId / oaId） */
    private final List<String> inputRefs;
    /** 已激活 skill id，会把 bundle 解压挂到 /skill/{skillId} */
    private final String activatedSkill;
    /** 超时（秒），入参校验后已 clamp 到 [1, MAX] */
    private final int timeoutSec;
    /** 产物类型提示，纯元信息 */
    private final String outputHint;

    private SandboxRequest(Builder b) {
        this.thread = b.thread;
        this.user = b.user;
        this.runId = b.runId;
        this.toolCallId = b.toolCallId;
        this.language = b.language == null ? "python" : b.language.toLowerCase();
        this.code = b.code;
        this.codeRef = b.codeRef;
        this.inputRefs = b.inputRefs == null ? Collections.<String>emptyList() : b.inputRefs;
        this.activatedSkill = b.activatedSkill;
        this.timeoutSec = b.timeoutSec;
        this.outputHint = b.outputHint;
    }

    public ThreadRoom getThread() { return thread; }
    public UserContext getUser() { return user; }
    public String getRunId() { return runId; }
    public String getToolCallId() { return toolCallId; }
    public String getLanguage() { return language; }
    public String getCode() { return code; }
    public String getCodeRef() { return codeRef; }
    public List<String> getInputRefs() { return inputRefs; }
    public String getActivatedSkill() { return activatedSkill; }
    public int getTimeoutSec() { return timeoutSec; }
    public String getOutputHint() { return outputHint; }

    public static Builder builder() { return new Builder(); }

    /**
     * 返回一个新的 SandboxRequest，code 字段被 resolved 后的脚本内容覆盖，其它字段复制.
     * 供 SandboxService 解析 codeRef 后，生成"语义等价 + code 已到位"的请求给下游逻辑用.
     */
    public SandboxRequest withResolvedCode(String resolvedCode) {
        return new Builder()
                .thread(this.thread)
                .user(this.user)
                .runId(this.runId)
                .toolCallId(this.toolCallId)
                .language(this.language)
                .code(resolvedCode)
                .codeRef(this.codeRef)        // 保留，日志 / 审计能看到脚本出处
                .inputRefs(this.inputRefs)
                .activatedSkill(this.activatedSkill)
                .timeoutSec(this.timeoutSec)
                .outputHint(this.outputHint)
                .build();
    }

    public static final class Builder {
        private ThreadRoom thread;
        private UserContext user;
        private String runId;
        private String toolCallId;
        private String language = "python";
        private String code;
        private String codeRef;
        private List<String> inputRefs;
        private String activatedSkill;
        private int timeoutSec = 30;
        private String outputHint;

        public Builder thread(ThreadRoom t) { this.thread = t; return this; }
        public Builder user(UserContext u) { this.user = u; return this; }
        public Builder runId(String v) { this.runId = v; return this; }
        public Builder toolCallId(String v) { this.toolCallId = v; return this; }
        public Builder language(String v) { this.language = v; return this; }
        public Builder code(String v) { this.code = v; return this; }
        public Builder codeRef(String v) { this.codeRef = v; return this; }
        public Builder inputRefs(List<String> v) { this.inputRefs = v; return this; }
        public Builder activatedSkill(String v) { this.activatedSkill = v; return this; }
        public Builder timeoutSec(int v) { this.timeoutSec = v; return this; }
        public Builder outputHint(String v) { this.outputHint = v; return this; }

        public SandboxRequest build() { return new SandboxRequest(this); }
    }
}
