import { z } from 'zod';
import { APIResponseSchema } from "../api.js";
import { ProjectResponseError } from "./util.js";
export const Resources = z.object({
    memory: z.string().default('500Mi').describe('The memory requirements'),
    cpu: z.string().default('500m').describe('The CPU requirements'),
    disk: z.string().default('500Mi').describe('The disk requirements'),
});
export const Mode = z.object({
    type: z
        .enum(['on-demand', 'provisioned'])
        .default('on-demand')
        .describe('on-demand or provisioned'),
    idle: z.string().optional().describe('duration in seconds if on-demand'),
});
export const ProjectBuildConfig = z.object({
    timeout: z.string().optional().describe('Build execution timeout (e.g. "30m")'),
    resources: z
        .object({
        memory: z.string().optional().describe('Build sandbox memory (e.g. "4Gi")'),
        cpu: z.string().optional().describe('Build sandbox CPU (e.g. "2")'),
        disk: z.string().optional().describe('Build sandbox disk (e.g. "4Gi")'),
    })
        .optional()
        .describe('Build sandbox resource limits'),
});
export const DeploymentConfig = z.object({
    resources: Resources.optional().describe('the resource requirements for your deployed project'),
    mode: Mode.optional().describe('the provisioning mode for the project'),
    dependencies: z
        .array(z.string().describe('APT dependencies to install prior to launching your project'))
        .optional(),
    domains: z.array(z.string().describe('the custom domain')).optional(),
});
const BaseFileFields = {
    filename: z.string().describe('the relative path for the file'),
    version: z.string().describe('the SHA256 content of the file'),
};
export const BuildEvalSchema = z.object({
    ...BaseFileFields,
    id: z.string().describe('the unique calculated id for the eval'),
    identifier: z.string().describe('the unique id for eval for the project across deployments'),
    name: z.string().describe('the name of the eval'),
    description: z.string().optional().describe('the eval description'),
    agentIdentifier: z.string().describe('the identifier of the agent'),
    projectId: z.string().describe('the project id'),
});
const BaseAgentFields = {
    ...BaseFileFields,
    id: z.string().describe('the unique calculated id for the agent'),
    agentId: z.string().describe('the unique id for agent for the project across deployments'),
    projectId: z.string().describe('the project id'),
    name: z.string().describe('the name of the agent'),
    description: z.string().optional().describe('the agent description'),
    evals: z.array(BuildEvalSchema).optional().describe('the evals for the agent'),
    schema: z
        .object({
        input: z.string().optional().describe('JSON schema for input (stringified JSON)'),
        output: z.string().optional().describe('JSON schema for output (stringified JSON)'),
    })
        .optional()
        .describe('input and output JSON schemas for the agent'),
};
export const BuildAgentSchema = z.object({
    ...BaseAgentFields,
});
export const BuildMetadataSchema = z.object({
    routes: z.array(z.object({
        id: z.string().describe('the unique calculated id for the route'),
        filename: z.string().describe('the relative path for the file'),
        path: z.string().describe('the route path'),
        method: z.enum(['get', 'post', 'put', 'delete', 'patch']).describe('the HTTP method'),
        version: z.string().describe('the SHA256 content of the file'),
        type: z.enum(['api', 'sms', 'email', 'cron', 'websocket', 'sse', 'stream']),
        agentIds: z
            .array(z.string())
            .optional()
            .describe('the agent ids associated with this route'),
        config: z
            .record(z.string(), z.unknown())
            .optional()
            .describe('type specific configuration'),
        schema: z
            .object({
            input: z.string().optional().describe('JSON schema for input (stringified JSON)'),
            output: z.string().optional().describe('JSON schema for output (stringified JSON)'),
        })
            .optional()
            .describe('input and output JSON schemas for the route'),
    })),
    agents: z.array(BuildAgentSchema),
    assets: z.array(z.object({
        filename: z.string().describe('the relative path for the file'),
        kind: z.string().describe('the type of asset'),
        contentType: z.string().describe('the content-type for the file'),
        contentEncoding: z.string().optional().describe('the content-encoding for the file'),
        size: z.number().describe('the size in bytes for the file'),
    })),
    project: z.object({
        id: z.string().describe('the project id'),
        name: z.string().describe('the name of the project (from package.json)'),
        version: z.string().optional().describe('the version of the project (from package.json)'),
        description: z
            .string()
            .optional()
            .describe('the description of the project (from package.json)'),
        keywords: z.array(z.string()).optional().describe('the keywords from package.json'),
        orgId: z.string().describe('the organization id for the project'),
    }),
    deployment: z.intersection(DeploymentConfig, z.object({
        id: z.string().describe('the deployment id'),
        date: z.string().describe('the date the deployment was created in UTC format'),
        git: z
            .object({
            repo: z.string().optional().describe('the repository name'),
            commit: z.string().optional().describe('the git commit sha'),
            message: z.string().optional().describe('the git commit message'),
            branch: z.string().optional().describe('the git branch'),
            tags: z.array(z.string()).optional().describe('the tags for the current branch'),
            pr: z.string().optional().describe('the pull request number'),
            provider: z.string().optional().describe('the CI provider'),
            trigger: z
                .string()
                .default('cli')
                .optional()
                .describe('the trigger that caused the build'),
            url: z
                .string()
                .url()
                .optional()
                .describe('the url to the commit for the CI provider'),
            buildUrl: z
                .string()
                .url()
                .optional()
                .describe('the url to the build for the CI provider'),
            event: z
                .enum(['pull_request', 'push', 'manual', 'workflow'])
                .default('manual')
                .optional()
                .describe('The type of Git-related event that triggered the deployment: pull_request (A pull request or merge request was opened, updated, or merged), push (A commit was pushed directly to a branch), manual (A deployment was triggered manually via CLI or a button), workflow (A deployment was triggered by an automated workflow, such as a CI pipeline)'),
            pull_request: z
                .object({
                number: z.number(),
                url: z.string().optional(),
            })
                .optional()
                .describe('This is only present when the deployment was triggered via a pull request.'),
        })
            .optional()
            .describe('git commit information'),
        build: z.object({
            bun: z.string().describe('the version of bun that was used to build the deployment'),
            agentuity: z.string().describe('the version of the agentuity runtime'),
            arch: z.string().describe('the machine architecture'),
            platform: z.string().describe('the machine os platform'),
        }),
    })),
});
export const CreateProjectDeploymentSchema = z.object({
    id: z.string().describe('the unique id for the deployment'),
    orgId: z.string().describe('the organization id'),
    publicKey: z.string().describe('the public key to use for encrypting the deployment'),
    buildLogsStreamURL: z
        .string()
        .optional()
        .describe('the URL for streaming build logs (PUT to write, GET to read)'),
});
export const CreateProjectDeploymentResponseSchema = APIResponseSchema(CreateProjectDeploymentSchema);
/**
 * Create a new project deployment
 *
 * @param client
 * @param projectId
 * @returns
 */
export async function projectDeploymentCreate(client, projectId, deploymentConfig) {
    const resp = await client.request('POST', `/cli/deploy/2/start/${projectId}`, CreateProjectDeploymentResponseSchema, deploymentConfig ?? {});
    if (resp.success) {
        return resp.data;
    }
    throw new ProjectResponseError({ message: resp.message });
}
export const DeploymentInstructionsSchema = z.object({
    deployment: z.string().describe('the url for uploading the encrypted deployment archive'),
    assets: z
        .record(z.string().describe('the asset id'), z.string().describe('the url for the asset upload'))
        .describe('the upload metadata for public assets'),
});
export const DeploymentInstructionsResponseSchema = APIResponseSchema(DeploymentInstructionsSchema);
/**
 * Update the deployment with the build metadata
 *
 * @param client
 * @param deploymentId
 * @returns
 */
export async function projectDeploymentUpdate(client, deploymentId, deployment, signal) {
    const resp = await client.request('PUT', `/cli/deploy/2/start/${deploymentId}`, DeploymentInstructionsResponseSchema, deployment, BuildMetadataSchema, signal);
    if (resp.success) {
        return resp.data;
    }
    throw new ProjectResponseError({ message: resp.message });
}
export const DeploymentCompleteSchema = z.object({
    streamId: z.string().optional().describe('the stream id for warmup logs'),
    publicUrls: z
        .object({
        latest: z.string().url().describe('the public url for the latest deployment'),
        deployment: z.string().url().describe('the public url for this deployment'),
        custom: z.array(z.string().describe('the custom domain')),
        vanityDeployment: z
            .string()
            .url()
            .nullable()
            .optional()
            .describe('the vanity url for this deployment'),
        vanityProject: z
            .string()
            .url()
            .nullable()
            .optional()
            .describe('the vanity url for the latest deployment'),
    })
        .describe('the map of public urls'),
});
export const DeploymentCompleteResponseSchema = APIResponseSchema(DeploymentCompleteSchema);
export const DeploymentStateValue = z.enum([
    'pending',
    'building',
    'deploying',
    'failed',
    'completed',
]);
export const DeploymentStatusSchema = z.object({
    state: DeploymentStateValue.describe('the current deployment state'),
});
export const DeploymentStatusResponseSchema = APIResponseSchema(DeploymentStatusSchema);
/**
 * Complete the deployment once build is uploaded
 *
 * @param client
 * @param deploymentId
 * @returns
 */
export async function projectDeploymentComplete(client, deploymentId, signal) {
    const resp = await client.request('POST', `/cli/deploy/2/complete/${deploymentId}`, DeploymentCompleteResponseSchema, undefined, undefined, signal);
    if (resp.success) {
        return resp.data;
    }
    throw new ProjectResponseError({
        message: resp.message || 'Deployment completion failed with unknown error',
    });
}
/**
 * Get the current provisioning status of a deployment
 *
 * @param client
 * @param deploymentId
 * @returns
 */
export async function projectDeploymentStatus(client, deploymentId, signal) {
    const resp = await client.request('GET', `/cli/deploy/2/status/${deploymentId}`, DeploymentStatusResponseSchema, undefined, undefined, signal);
    if (resp.success) {
        return resp.data;
    }
    throw new ProjectResponseError({ message: resp.message });
}
export const ClientDiagnosticsErrorSchema = z.object({
    type: z.enum(['file', 'general']),
    scope: z.enum(['typescript', 'ast', 'build', 'bundler', 'validation', 'deploy']),
    path: z.string().optional(),
    line: z.number().optional(),
    column: z.number().optional(),
    message: z.string(),
    code: z.string().optional(),
});
export const ClientDiagnosticsTimingSchema = z.object({
    name: z.string(),
    startedAt: z.string(),
    completedAt: z.string(),
    durationMs: z.number(),
});
export const ClientDiagnosticsSchema = z.object({
    success: z.boolean(),
    errors: z.array(ClientDiagnosticsErrorSchema),
    warnings: z.array(ClientDiagnosticsErrorSchema),
    diagnostics: z.array(ClientDiagnosticsTimingSchema),
    error: z.string().optional(),
});
export const DeploymentFailPayloadSchema = z.object({
    error: z.string().optional(),
    diagnostics: ClientDiagnosticsSchema.optional(),
});
export const DeploymentFailResponseSchema = z.object({
    state: z.literal('failed'),
});
export const DeploymentFailAPIResponseSchema = APIResponseSchema(DeploymentFailResponseSchema);
/**
 * Report a deployment failure from the client
 *
 * @param client
 * @param deploymentId
 * @param payload - Error message and/or structured diagnostics
 * @returns
 */
export async function projectDeploymentFail(client, deploymentId, payload) {
    const resp = await client.request('POST', `/cli/deploy/2/fail/${deploymentId}`, DeploymentFailAPIResponseSchema, payload, DeploymentFailPayloadSchema);
    if (!resp.success) {
        throw new ProjectResponseError({ message: resp.message });
    }
}
//# sourceMappingURL=deploy.js.map