/**
 * Zod schemas for runtime validation of deserialized Redis data
 *
 * These schemas validate data after JSON.parse() to prevent
 * corrupted or tampered data from propagating silently.
 */

import { z } from "zod";

/**
 * Task status enum schema
 */
export const TaskStatusSchema = z.enum(["pending", "assigned", "executing", "completed", "failed"]);

/**
 * Agent status enum schema
 */
export const AgentStatusSchema = z.enum(["spawning", "running", "completed", "failed", "killed"]);

/**
 * Task context schema
 */
export const TaskContextSchema = z.object({
  repository: z.string(),
  branch: z.string(),
  workItems: z.array(z.string()),
  skills: z.array(z.string()).optional(),
});

/**
 * Task state schema - validates deserialized task data from Redis
 */
export const TaskStateSchema = z.object({
  taskId: z.string(),
  status: TaskStatusSchema,
  agentId: z.string().optional(),
  context: TaskContextSchema,
  createdAt: z.string(),
  updatedAt: z.string(),
  metadata: z.record(z.unknown()).optional(),
});

/**
 * Agent state schema - validates deserialized agent data from Redis
 */
export const AgentStateSchema = z.object({
  agentId: z.string(),
  status: AgentStatusSchema,
  taskId: z.string(),
  startedAt: z.string().optional(),
  completedAt: z.string().optional(),
  error: z.string().optional(),
  metadata: z.record(z.unknown()).optional(),
});

/**
 * Event type enum schema
 */
export const EventTypeSchema = z.enum([
  "agent.spawned",
  "agent.running",
  "agent.completed",
  "agent.failed",
  "agent.killed",
  "agent.cleanup",
  "task.assigned",
  "task.queued",
  "task.processing",
  "task.retry",
  "task.executing",
  "task.completed",
  "task.failed",
]);

/**
 * Agent event schema
 */
export const AgentEventSchema = z.object({
  type: z.enum([
    "agent.spawned",
    "agent.running",
    "agent.completed",
    "agent.failed",
    "agent.killed",
    "agent.cleanup",
  ]),
  timestamp: z.string(),
  agentId: z.string(),
  taskId: z.string(),
  error: z.string().optional(),
  cleanup: z
    .object({
      docker: z.boolean(),
      worktree: z.boolean(),
      state: z.boolean(),
    })
    .optional(),
});

/**
 * Task event schema
 */
export const TaskEventSchema = z.object({
  type: z.enum([
    "task.assigned",
    "task.queued",
    "task.processing",
    "task.retry",
    "task.executing",
    "task.completed",
    "task.failed",
  ]),
  timestamp: z.string(),
  taskId: z.string().optional(),
  agentId: z.string().optional(),
  error: z.string().optional(),
  data: z.record(z.unknown()).optional(),
});

/**
 * Combined orchestrator event schema (discriminated union)
 */
export const OrchestratorEventSchema = z.union([AgentEventSchema, TaskEventSchema]);
