/**
 * Trigger.dev Job: Test Single Agent Container Spawning
 *
 * Phase 1: Single Agent Spawn Testing
 *
 * This job spawns a single CFN agent in an isolated Docker container
 * to validate container execution, resource limits, and output capture.
 *
 * Requirements:
 * - Container network: cfn-network
 * - Resource limits: 2 CPU, 4GB RAM
 * - Volume: /workspace:/workspace (read/write)
 * - Auto-remove: true (--rm for cleanup)
 * - Image: cfn-agent:test
 *
 * Environment variables passed to agent:
 * - TASK_ID: Unique task identifier from trigger.dev
 * - AGENT_TYPE: Type of agent being spawned
 *
 * Success criteria:
 * - Agent container spawns successfully
 * - Container executes CLI agent command
 * - stdout/stderr captured in job logs
 * - Container exits cleanly with --rm
 * - Exit code propagated to trigger.dev
 */

import { client } from "@trigger.dev/sdk";
import { z } from "zod";
import { exec } from "child_process";
import { promisify } from "util";

const execAsync = promisify(exec);

/**
 * Payload schema for test.agent.spawn event
 */
const TestAgentSpawnSchema = z.object({
  agentType: z.string().describe("Type of agent to spawn (e.g., backend-developer, frontend-developer)"),
  taskDescription: z.string().describe("Task description for the agent to execute"),
});

/**
 * Container spawning result with metadata
 */
interface ContainerResult {
  stdout: string;
  stderr: string;
  containerName: string;
  exitCode: number;
  executionTimeMs: number;
}

/**
 * Test Single Agent Job
 *
 * Spawns a single agent container for Phase 1 validation testing.
 */
export const testSingleAgentJob = client.defineJob({
  id: "test-single-agent",
  name: "Test Single Agent Container Spawning",
  version: "0.1.0",
  trigger: {
    event: {
      name: "test.agent.spawn",
      schema: TestAgentSpawnSchema,
    },
  },
  run: async (payload, io, ctx) => {
    const { agentType, taskDescription } = payload;

    // Generate unique container name
    const containerName = `cfn-agent-${ctx.run.id}-${Date.now()}`;
    const startTime = Date.now();

    io.logger.info("Spawning agent container", {
      containerName,
      agentType,
      taskId: ctx.run.id,
      taskDescription,
    });

    try {
      // Spawn agent container with resource limits and network configuration
      const result = await io.runTask<ContainerResult>(
        "spawn-agent-container",
        async () => {
          // Build Docker command with all required parameters
          const dockerCmd = [
            "docker run --rm",
            `--name ${containerName}`,
            "--network cfn-network",
            "--cpus=2",
            "--memory=4g",
            `-e TASK_ID=${ctx.run.id}`,
            `-e AGENT_TYPE=${agentType}`,
            "-v /workspace:/workspace",
            "cfn-agent:test",
            agentType,
            `--task "${taskDescription}"`,
          ].join(" ");

          io.logger.info("Executing Docker command", { command: dockerCmd });

          try {
            // Execute Docker command and capture output
            const { stdout, stderr } = await execAsync(dockerCmd, {
              // Set timeout to 30 minutes (agent execution can take time)
              timeout: 30 * 60 * 1000,
              maxBuffer: 10 * 1024 * 1024, // 10MB buffer for large outputs
            });

            const executionTimeMs = Date.now() - startTime;

            io.logger.info("Agent container completed successfully", {
              containerName,
              executionTimeMs,
              stdoutLength: stdout.length,
              stderrLength: stderr.length,
            });

            return {
              stdout,
              stderr,
              containerName,
              exitCode: 0,
              executionTimeMs,
            };
          } catch (execError: any) {
            // Handle container execution errors
            const executionTimeMs = Date.now() - startTime;
            const exitCode = execError.code || 1;

            io.logger.error("Agent container execution failed", {
              containerName,
              exitCode,
              executionTimeMs,
              error: execError.message,
              stdout: execError.stdout || "",
              stderr: execError.stderr || "",
            });

            // Return error details for debugging
            return {
              stdout: execError.stdout || "",
              stderr: execError.stderr || execError.message,
              containerName,
              exitCode,
              executionTimeMs,
            };
          }
        },
        {
          name: `Spawn ${agentType}`,
          description: `Spawning ${agentType} agent with task: ${taskDescription}`,
        }
      );

      // Log final results
      io.logger.info("Agent execution completed", {
        containerName: result.containerName,
        exitCode: result.exitCode,
        executionTimeMs: result.executionTimeMs,
        success: result.exitCode === 0,
      });

      // Return results with metadata
      return {
        success: result.exitCode === 0,
        containerName: result.containerName,
        agentType,
        taskId: ctx.run.id,
        executionTimeMs: result.executionTimeMs,
        exitCode: result.exitCode,
        output: {
          stdout: result.stdout,
          stderr: result.stderr,
        },
      };
    } catch (error: any) {
      // Handle unexpected job-level errors
      io.logger.error("Job execution failed", {
        error: error.message,
        stack: error.stack,
        containerName,
      });

      throw error;
    }
  },
});

/**
 * Export job for registration with trigger.dev
 */
export default testSingleAgentJob;
