import { z } from 'zod';
import { APIResponseSchema } from "../api.js";
import { NPM_PACKAGE_NAME_PATTERN } from "./snapshot-build.js";
import { throwSandboxError } from "./util.js";
export const SandboxCreateRequestSchema = z
    .object({
    projectId: z.string().optional().describe('Project ID to associate the sandbox with'),
    runtime: z.string().optional().describe('Runtime name (e.g., "bun:1", "python:3.14")'),
    runtimeId: z.string().optional().describe('Runtime ID (e.g., "srt_xxx")'),
    name: z.string().optional().describe('Optional sandbox name'),
    description: z.string().optional().describe('Optional sandbox description'),
    resources: z
        .object({
        memory: z.string().optional().describe('Memory limit (e.g., "512Mi", "1Gi")'),
        cpu: z.string().optional().describe('CPU limit (e.g., "0.5", "1")'),
        disk: z.string().optional().describe('Disk size limit (e.g., "1Gi", "10Gi")'),
    })
        .optional()
        .describe('Resource constraints for the sandbox'),
    env: z
        .record(z.string(), z.string())
        .optional()
        .describe('Environment variables to set in the sandbox'),
    network: z
        .object({
        enabled: z.boolean().optional().describe('Whether network access is enabled'),
        port: z
            .number()
            .int()
            .min(1024)
            .max(65535)
            .optional()
            .describe('Port to expose from the sandbox (1024-65535)'),
    })
        .optional()
        .describe('Network configuration for the sandbox'),
    stream: z
        .object({
        stdout: z.string().optional().describe('Stream ID for stdout output'),
        stderr: z.string().optional().describe('Stream ID for stderr output'),
        stdin: z.string().optional().describe('Stream ID for stdin input'),
        timestamps: z.boolean().optional().describe('Whether to include timestamps in output'),
    })
        .optional()
        .describe('Stream configuration for I/O redirection'),
    timeout: z
        .object({
        idle: z.string().optional().describe('Idle timeout duration (e.g., "5m", "1h")'),
        execution: z.string().optional().describe('Maximum execution time (e.g., "30m", "2h")'),
        paused: z
            .string()
            .optional()
            .describe('Maximum time sandbox can remain paused before termination (e.g., "24h", "0s" for infinite)'),
    })
        .optional()
        .describe('Timeout settings for the sandbox'),
    command: z
        .object({
        exec: z.array(z.string()).describe('Command and arguments to execute'),
        files: z
            .array(z.object({
            path: z
                .string()
                .describe('Path to the file relative to the sandbox workspace'),
            content: z.string().describe('Base64-encoded file content'),
        }))
            .optional()
            .describe('Files to write before execution (deprecated: use top-level files)'),
        mode: z
            .enum(['oneshot', 'interactive'])
            .optional()
            .describe('Execution mode: oneshot runs once, interactive keeps running'),
    })
        .optional()
        .describe('Initial command to run in the sandbox'),
    files: z
        .array(z.object({
        path: z.string().describe('Path to the file relative to the sandbox workspace'),
        content: z.string().describe('Base64-encoded file content'),
    }))
        .optional()
        .describe('Files to write to sandbox on creation'),
    snapshot: z.string().optional().describe('Snapshot ID to restore the sandbox from'),
    dependencies: z
        .array(z.string())
        .optional()
        .describe('Apt packages to install when creating the sandbox'),
    packages: z
        .array(z
        .string()
        .regex(NPM_PACKAGE_NAME_PATTERN, 'Invalid npm/bun package specifier: must not contain whitespace, semicolons, backticks, pipes, or dollar signs'))
        .optional()
        .describe('npm/bun packages to install globally when creating the sandbox'),
    metadata: z
        .record(z.string(), z.unknown())
        .optional()
        .describe('Optional user-defined metadata to associate with the sandbox'),
    scopes: z
        .array(z.string())
        .optional()
        .describe('Permission scopes for automatic service access (e.g., "services:read", "services:write").'),
})
    .refine((data) => {
    // If snapshot is provided, runtime and runtimeId must not be provided
    if (data.snapshot) {
        return !data.runtime && !data.runtimeId;
    }
    return true;
}, {
    message: 'cannot specify both snapshot and runtime; snapshot includes its own runtime',
    path: ['snapshot'],
})
    .describe('Request body for creating a new sandbox');
export const SandboxCreateDataSchema = z
    .object({
    sandboxId: z.string().describe('Unique identifier for the created sandbox'),
    status: z
        .enum([
        'creating',
        'idle',
        'running',
        'paused',
        'stopping',
        'suspended',
        'terminated',
        'failed',
    ])
        .describe('Current status of the sandbox'),
    executionId: z
        .string()
        .optional()
        .describe('Initial execution identifier for oneshot sandbox creation'),
    url: z
        .string()
        .optional()
        .describe('Public URL for the sandbox (only set when a network port is configured)'),
    stdoutStreamId: z.string().optional().describe('Stream ID for reading stdout'),
    stdoutStreamUrl: z.string().optional().describe('URL for streaming stdout output'),
    stderrStreamId: z.string().optional().describe('Stream ID for reading stderr'),
    stderrStreamUrl: z.string().optional().describe('URL for streaming stderr output'),
    auditStreamId: z.string().optional().describe('Stream ID for reading audit events'),
    auditStreamUrl: z.string().optional().describe('URL for streaming audit events'),
})
    .describe('Response data from sandbox creation');
export const SandboxCreateResponseSchema = APIResponseSchema(SandboxCreateDataSchema);
export const SandboxCreateParamsSchema = z.object({
    options: z.custom().optional().describe('Optional sandbox create options'),
    orgId: z.string().optional().describe('Optional org id for CLI auth context'),
});
/**
 * Creates a new sandbox instance.
 *
 * @param client - The API client to use for the request
 * @param params - Parameters for creating the sandbox
 * @returns The created sandbox response including sandbox ID and stream URLs
 * @throws {SandboxResponseError} If the sandbox creation fails
 */
export async function sandboxCreate(client, params = {}) {
    const { options = {}, orgId } = params;
    const body = {};
    if (options.projectId) {
        body.projectId = options.projectId;
    }
    if (options.runtime) {
        body.runtime = options.runtime;
    }
    if (options.runtimeId) {
        body.runtimeId = options.runtimeId;
    }
    if (options.name) {
        body.name = options.name;
    }
    if (options.description) {
        body.description = options.description;
    }
    if (options.resources) {
        body.resources = options.resources;
    }
    if (options.env) {
        body.env = options.env;
    }
    if (options.network) {
        body.network = options.network;
    }
    if (options.stream) {
        body.stream = options.stream;
    }
    if (options.timeout) {
        body.timeout = options.timeout;
    }
    if (options.command) {
        body.command = {
            exec: options.command.exec,
            mode: options.command.mode,
            files: options.command.files?.map((f) => ({
                path: f.path,
                content: f.content.toString('base64'),
            })),
        };
    }
    if (options.files && options.files.length > 0) {
        body.files = options.files.map((f) => ({
            path: f.path,
            content: f.content.toString('base64'),
        }));
    }
    if (options.snapshot) {
        body.snapshot = options.snapshot;
    }
    if (options.dependencies && options.dependencies.length > 0) {
        body.dependencies = options.dependencies;
    }
    if (options.packages && options.packages.length > 0) {
        body.packages = options.packages;
    }
    if (options.metadata) {
        body.metadata = options.metadata;
    }
    if (options.scopes && options.scopes.length > 0) {
        body.scopes = options.scopes;
    }
    const queryParams = new URLSearchParams();
    if (orgId) {
        queryParams.set('orgId', orgId);
    }
    const queryString = queryParams.toString();
    const url = `/sandbox${queryString ? `?${queryString}` : ''}`;
    const resp = await client.post(url, body, SandboxCreateResponseSchema, SandboxCreateRequestSchema);
    if (resp.success) {
        return resp.data;
    }
    throwSandboxError(resp, {});
}
//# sourceMappingURL=create.js.map