import Testing

@testable import NucleicCore

@Suite("Codex in the Nucleic runtime")
struct CodexRuntimeEnvironmentTests {
    private func run(
        sandbox: SandboxMode? = nil,
        allowHostExec: Bool = false,
        allowMacVMExec: Bool = false,
        allowLinuxVMComputer: Bool = false,
        allowAgentContainers: Bool = false,
        guidance: String? = "provider-neutral guidance"
    ) -> RunSpec {
        RunSpec(
            sessionID: SessionID(rawValue: "codex-runtime"), worktree: "/repo",
            prompt: AgentInput(parts: []), sandbox: sandbox,
            allowHostExec: allowHostExec, allowMacVMExec: allowMacVMExec,
            allowLinuxVMComputer: allowLinuxVMComputer,
            allowAgentContainers: allowAgentContainers,
            appendSystemPrompt: guidance)
    }

    @Test func containerInstructionsExplainBwrapAndAdvertiseOnlyEnabledExecutionTools() {
        let instructions = CodexRuntimeEnvironment.developerInstructions(
            for: run(allowHostExec: true, allowAgentContainers: true),
            containerized: true) ?? ""

        #expect(instructions.contains("Nucleic Codex runtime"))
        #expect(instructions.contains("`bwrap`"))
        #expect(instructions.contains("not a broken dependency"))
        #expect(instructions.contains("Never try to invoke, install, repair, or diagnose"))
        #expect(instructions.contains("tools actually present in your tool list"))
        #expect(instructions.contains("`linux_container`"))
        #expect(instructions.contains("`host_exec`"))
        #expect(!instructions.contains("`mac_vm_exec`"))
        #expect(instructions.hasSuffix("provider-neutral guidance"))
    }

    @Test func toolSummaryFollowsThePerTurnCapabilities() {
        let names = CodexRuntimeEnvironment.platformToolNames(for: run(
            allowMacVMExec: true, allowLinuxVMComputer: true))

        #expect(names.contains("mac_vm_exec"))
        #expect(names.contains("mac_vm_control"))
        #expect(names.contains("linux_vm_computer"))
        #expect(names.contains("linux_vm_computer_batch"))
        #expect(names.contains("linux_vm_control"))
        #expect(!names.contains("host_exec"))
        #expect(!names.contains("linux_container"))
    }

    @Test func hostRunsKeepTheirOriginalGuidanceAndRequestedSandbox() {
        let spec = run(sandbox: .readOnly)
        #expect(CodexRuntimeEnvironment.developerInstructions(
            for: spec, containerized: false) == "provider-neutral guidance")
        #expect(CodexRuntimeEnvironment.sandboxMode(
            containerized: false, requested: spec.sandbox) == .readOnly)
    }

    @Test func containerizedExecUsesCodexsExternalSandboxMode() {
        let args = CodexRuntimeEnvironment.execIsolationArgs(
            containerized: true, requested: .workspaceWrite)
        #expect(args == ["--dangerously-bypass-approvals-and-sandbox"])
        #expect(!args.contains("--sandbox"))
    }

    @Test func hostExecRetainsTheRequestedCodexSandboxAndNeverApprovalPolicy() {
        #expect(CodexRuntimeEnvironment.execIsolationArgs(
            containerized: false, requested: .readOnly) == [
                "--sandbox", "read-only", "--ask-for-approval", "never",
            ])
    }

    /// `threadRuntimeParams` feeds both thread/start and thread/resume. Keeping the assertion on the
    /// shared builder prevents a future resume refactor from reviving a persisted workspace sandbox.
    @Test func appServerRuntimeParamsReassertOuterSandboxAndInstructionsOnResume() {
        let params = CodexAppServerBackend.threadRuntimeParams(
            for: run(sandbox: .readOnly, allowHostExec: true),
            isHostRun: false, approvalPolicy: "on-request")

        #expect(params["sandbox"]?.stringValue == "danger-full-access")
        #expect(params["approvalPolicy"]?.stringValue == "on-request")
        #expect(params["approvalsReviewer"]?.stringValue == "user")
        #expect(params["developerInstructions"]?.stringValue?.contains("`bwrap`") == true)
        #expect(params["developerInstructions"]?.stringValue?.contains("`host_exec`") == true)
    }
}
