package main

import "github.com/orchard9/rdev/pkg/api"

func registerAgentPaths(spec *api.OpenAPISpec) {
	spec.AddPath("/agents", "get", withAuth(
		"List code agents",
		`Returns all registered code agent providers and their status.

Shows which agents are available, their supported models, and the current default.`,
		"Code Agents",
		"projects:read",
		`{
  "agents": [
    {
      "provider": "claudecode",
      "name": "Claude Code",
      "available": true,
      "default": true,
      "supported_models": ["claude-sonnet-4-20250514"],
      "default_model": "claude-sonnet-4-20250514"
    },
    {
      "provider": "opencode",
      "name": "OpenCode",
      "available": false,
      "default": false,
      "supported_models": ["gpt-4o", "claude-sonnet-4-20250514"],
      "default_model": "claude-sonnet-4-20250514"
    }
  ],
  "default_agent": "claudecode",
  "total_agents": 2,
  "available_count": 1
}`,
	))

	spec.AddPath("/agents/health", "get", withAuth(
		"Get agent health status",
		`Returns the health status of all registered code agents.

Checks connectivity to each agent backend and reports availability.`,
		"Code Agents",
		"projects:read",
		`{
  "agents": [
    {
      "provider": "claudecode",
      "name": "Claude Code",
      "healthy": true,
      "message": "available",
      "latency": "125ms",
      "checked_at": "2026-01-27T12:00:00Z"
    },
    {
      "provider": "opencode",
      "name": "OpenCode",
      "healthy": false,
      "message": "unavailable",
      "latency": "5.002s",
      "checked_at": "2026-01-27T12:00:00Z"
    }
  ],
  "healthy_count": 1,
  "total_count": 2,
  "default_agent": "claudecode",
  "default_healthy": true
}`,
	))

	spec.AddPath("/agents/{provider}", "get", withAuthAndParams(
		"Get agent capabilities",
		`Returns detailed capabilities for a specific code agent provider.

Includes supported features, models, and configuration options.`,
		"Code Agents",
		"projects:read",
		[]param{{Name: "provider", In: "path", Description: "Agent provider ID (e.g., 'claudecode', 'opencode')", Required: true}},
	))

	spec.AddPath("/agents/default", "post", withAuthAndBody(
		"Set default agent",
		`Changes the default code agent used for command execution.

The specified provider must be registered and ideally available.`,
		"Code Agents",
		"admin",
		`{"provider": "opencode"}`,
		`{
  "default_agent": "opencode",
  "message": "default agent updated"
}`,
	))
}

// param represents an OpenAPI parameter.
type param struct {
	Name        string
	In          string
	Description string
	Required    bool
}

// withAuth creates an operation that requires authentication.
func withAuth(summary, description, tag, scope, example string) map[string]any {
	return map[string]any{
		"summary":     summary,
		"description": description + "\n\n**Required scope**: `" + scope + "`",
		"tags":        []string{tag},
		"security": []map[string]any{
			{"ApiKeyAuth": []string{}},
		},
		"responses": map[string]any{
			"200": map[string]any{
				"description": "Success",
				"content": map[string]any{
					"application/json": map[string]any{
						"example": example,
					},
				},
			},
			"401": map[string]any{"description": "Unauthorized - Missing or invalid API key"},
			"403": map[string]any{"description": "Forbidden - Insufficient permissions"},
		},
	}
}

// withAuthAndBody creates an operation with auth and request body.
func withAuthAndBody(summary, description, tag, scope, requestExample, responseExample string) map[string]any {
	return map[string]any{
		"summary":     summary,
		"description": description + "\n\n**Required scope**: `" + scope + "`",
		"tags":        []string{tag},
		"security": []map[string]any{
			{"ApiKeyAuth": []string{}},
		},
		"requestBody": map[string]any{
			"required": true,
			"content": map[string]any{
				"application/json": map[string]any{
					"example": requestExample,
				},
			},
		},
		"responses": map[string]any{
			"201": map[string]any{
				"description": "Created",
				"content": map[string]any{
					"application/json": map[string]any{
						"example": responseExample,
					},
				},
			},
			"400": map[string]any{"description": "Bad Request - Invalid input"},
			"401": map[string]any{"description": "Unauthorized - Missing or invalid API key"},
			"403": map[string]any{"description": "Forbidden - Insufficient permissions"},
		},
	}
}

// withAuthAndParams creates an operation with auth and path parameters.
func withAuthAndParams(summary, description, tag, scope string, params []param) map[string]any {
	parameters := make([]map[string]any, len(params))
	for i, p := range params {
		parameters[i] = map[string]any{
			"name":        p.Name,
			"in":          p.In,
			"description": p.Description,
			"required":    p.Required,
			"schema":      map[string]any{"type": "string"},
		}
	}
	return map[string]any{
		"summary":     summary,
		"description": description + "\n\n**Required scope**: `" + scope + "`",
		"tags":        []string{tag},
		"security": []map[string]any{
			{"ApiKeyAuth": []string{}},
		},
		"parameters": parameters,
		"responses": map[string]any{
			"200": map[string]any{"description": "Success"},
			"401": map[string]any{"description": "Unauthorized - Missing or invalid API key"},
			"403": map[string]any{"description": "Forbidden - Insufficient permissions"},
			"404": map[string]any{"description": "Not Found"},
		},
	}
}

// withAuthBodyAndParams creates an operation with auth, body, and params.
func withAuthBodyAndParams(summary, description, tag, scope string, params []param, requestExample, responseExample string) map[string]any {
	parameters := make([]map[string]any, len(params))
	for i, p := range params {
		parameters[i] = map[string]any{
			"name":        p.Name,
			"in":          p.In,
			"description": p.Description,
			"required":    p.Required,
			"schema":      map[string]any{"type": "string"},
		}
	}
	return map[string]any{
		"summary":     summary,
		"description": description + "\n\n**Required scope**: `" + scope + "`",
		"tags":        []string{tag},
		"security": []map[string]any{
			{"ApiKeyAuth": []string{}},
		},
		"parameters": parameters,
		"requestBody": map[string]any{
			"required": true,
			"content": map[string]any{
				"application/json": map[string]any{
					"example": requestExample,
				},
			},
		},
		"responses": map[string]any{
			"201": map[string]any{
				"description": "Created",
				"content": map[string]any{
					"application/json": map[string]any{
						"example": responseExample,
					},
				},
			},
			"400": map[string]any{"description": "Bad Request - Invalid input"},
			"401": map[string]any{"description": "Unauthorized - Missing or invalid API key"},
			"403": map[string]any{"description": "Forbidden - Insufficient permissions"},
		},
	}
}

func registerWorkerPaths(spec *api.OpenAPISpec) {
	spec.AddPath("/workers", "get", withAuth(
		"List workers",
		"Returns all registered workers in the pool with status summary.",
		"Workers",
		"admin",
		`{
  "workers": [
    {
      "id": "rdev-worker-0",
      "hostname": "rdev-worker-0.rdev.svc",
      "status": "idle",
      "capabilities": ["build", "test", "deploy"],
      "registered_at": "2026-01-27T12:00:00Z",
      "last_heartbeat": "2026-01-27T12:05:00Z",
      "version": "1.0.0"
    }
  ],
  "total": 1,
  "summary": {"idle": 1, "busy": 0, "draining": 0, "offline": 0}
}`,
	))

	spec.AddPath("/workers/{workerId}", "get", withAuthAndParams(
		"Get worker",
		"Returns details for a specific worker.",
		"Workers",
		"admin",
		[]param{{Name: "workerId", In: "path", Description: "Worker ID", Required: true}},
	))

	spec.AddPath("/workers/{workerId}/drain", "post", withAuthAndParams(
		"Drain worker",
		"Sets a worker to draining status. It will finish its current task but stop accepting new work.",
		"Workers",
		"admin",
		[]param{{Name: "workerId", In: "path", Description: "Worker ID", Required: true}},
	))
}

func registerSDLCPaths(spec *api.OpenAPISpec) {
	// State and classifier
	spec.AddPath("/projects/{id}/sdlc/state", "get", withAuthAndParams(
		"Get SDLC state",
		"Returns the global SDLC state for a project.",
		"SDLC",
		"projects:read",
		[]param{{Name: "id", In: "path", Description: "Project ID", Required: true}},
	))

	spec.AddPath("/projects/{id}/sdlc/next", "get", map[string]any{
		"summary":     "Get next action",
		"description": "Returns the classifier's recommended next action.\n\n**Required scope**: `projects:read`",
		"tags":        []string{"SDLC"},
		"security":    []map[string]any{{"ApiKeyAuth": []string{}}},
		"parameters": []map[string]any{
			{"name": "id", "in": "path", "description": "Project ID", "required": true, "schema": map[string]any{"type": "string"}},
			{"name": "feature", "in": "query", "description": "Feature slug (optional)", "schema": map[string]any{"type": "string"}},
		},
		"responses": map[string]any{
			"200": map[string]any{"description": "Success"},
			"401": map[string]any{"description": "Unauthorized"},
		},
	})

	// Features
	spec.AddPath("/projects/{id}/sdlc/features", "get", withAuthAndParams(
		"List features",
		"Returns all features in the project.",
		"SDLC",
		"projects:read",
		[]param{{Name: "id", In: "path", Description: "Project ID", Required: true}},
	))

	spec.AddPath("/projects/{id}/sdlc/features", "post", withAuthBodyAndParams(
		"Create feature",
		"Creates a new feature in the draft phase.",
		"SDLC",
		"projects:execute",
		[]param{{Name: "id", In: "path", Description: "Project ID", Required: true}},
		`{"slug": "auth-flow", "title": "User Authentication Flow"}`,
		`{"slug": "auth-flow", "title": "User Authentication Flow", "phase": "draft"}`,
	))

	spec.AddPath("/projects/{id}/sdlc/features/{slug}", "get", withAuthAndParams(
		"Get feature",
		"Returns details for a specific feature.",
		"SDLC",
		"projects:read",
		[]param{
			{Name: "id", In: "path", Description: "Project ID", Required: true},
			{Name: "slug", In: "path", Description: "Feature slug", Required: true},
		},
	))

	spec.AddPath("/projects/{id}/sdlc/features/{slug}", "delete", withAuthAndParams(
		"Delete feature",
		"Deletes a feature from the project.",
		"SDLC",
		"projects:execute",
		[]param{
			{Name: "id", In: "path", Description: "Project ID", Required: true},
			{Name: "slug", In: "path", Description: "Feature slug", Required: true},
		},
	))

	spec.AddPath("/projects/{id}/sdlc/features/{slug}/transition", "post", withAuthBodyAndParams(
		"Transition feature",
		"Moves a feature to a new phase.",
		"SDLC",
		"projects:execute",
		[]param{
			{Name: "id", In: "path", Description: "Project ID", Required: true},
			{Name: "slug", In: "path", Description: "Feature slug", Required: true},
		},
		`{"phase": "specified"}`,
		`{"status": "transitioned", "phase": "specified"}`,
	))

	spec.AddPath("/projects/{id}/sdlc/features/{slug}/block", "post", withAuthBodyAndParams(
		"Block feature",
		"Adds a blocker reason to a feature.",
		"SDLC",
		"projects:execute",
		[]param{
			{Name: "id", In: "path", Description: "Project ID", Required: true},
			{Name: "slug", In: "path", Description: "Feature slug", Required: true},
		},
		`{"reason": "Waiting for API design"}`,
		`{"status": "blocked"}`,
	))

	spec.AddPath("/projects/{id}/sdlc/features/{slug}/unblock", "post", withAuthAndParams(
		"Unblock feature",
		"Removes all blockers from a feature.",
		"SDLC",
		"projects:execute",
		[]param{
			{Name: "id", In: "path", Description: "Project ID", Required: true},
			{Name: "slug", In: "path", Description: "Feature slug", Required: true},
		},
	))

	// Artifacts
	spec.AddPath("/projects/{id}/sdlc/features/{slug}/artifacts", "get", withAuthAndParams(
		"Get artifact status",
		"Returns artifact statuses for a feature.",
		"SDLC",
		"projects:read",
		[]param{
			{Name: "id", In: "path", Description: "Project ID", Required: true},
			{Name: "slug", In: "path", Description: "Feature slug", Required: true},
		},
	))

	spec.AddPath("/projects/{id}/sdlc/features/{slug}/artifacts/{type}/approve", "post", withAuthAndParams(
		"Approve artifact",
		"Approves a feature artifact.",
		"SDLC",
		"projects:execute",
		[]param{
			{Name: "id", In: "path", Description: "Project ID", Required: true},
			{Name: "slug", In: "path", Description: "Feature slug", Required: true},
			{Name: "type", In: "path", Description: "Artifact type (spec, design, tasks, qa_plan, review, audit, qa_results)", Required: true},
		},
	))

	spec.AddPath("/projects/{id}/sdlc/features/{slug}/artifacts/{type}/reject", "post", withAuthAndParams(
		"Reject artifact",
		"Rejects a feature artifact.",
		"SDLC",
		"projects:execute",
		[]param{
			{Name: "id", In: "path", Description: "Project ID", Required: true},
			{Name: "slug", In: "path", Description: "Feature slug", Required: true},
			{Name: "type", In: "path", Description: "Artifact type", Required: true},
		},
	))

	// Tasks
	spec.AddPath("/projects/{id}/sdlc/features/{slug}/tasks", "get", withAuthAndParams(
		"List tasks",
		"Returns all tasks for a feature.",
		"SDLC",
		"projects:read",
		[]param{
			{Name: "id", In: "path", Description: "Project ID", Required: true},
			{Name: "slug", In: "path", Description: "Feature slug", Required: true},
		},
	))

	spec.AddPath("/projects/{id}/sdlc/features/{slug}/tasks", "post", withAuthBodyAndParams(
		"Add task",
		"Adds a new task to a feature.",
		"SDLC",
		"projects:execute",
		[]param{
			{Name: "id", In: "path", Description: "Project ID", Required: true},
			{Name: "slug", In: "path", Description: "Feature slug", Required: true},
		},
		`{"title": "Implement login handler"}`,
		`{"id": "task-001", "title": "Implement login handler", "status": "pending"}`,
	))

	spec.AddPath("/projects/{id}/sdlc/features/{slug}/tasks/{taskId}/start", "post", withAuthAndParams(
		"Start task",
		"Marks a task as in-progress.",
		"SDLC",
		"projects:execute",
		[]param{
			{Name: "id", In: "path", Description: "Project ID", Required: true},
			{Name: "slug", In: "path", Description: "Feature slug", Required: true},
			{Name: "taskId", In: "path", Description: "Task ID", Required: true},
		},
	))

	spec.AddPath("/projects/{id}/sdlc/features/{slug}/tasks/{taskId}/complete", "post", withAuthAndParams(
		"Complete task",
		"Marks a task as complete.",
		"SDLC",
		"projects:execute",
		[]param{
			{Name: "id", In: "path", Description: "Project ID", Required: true},
			{Name: "slug", In: "path", Description: "Feature slug", Required: true},
			{Name: "taskId", In: "path", Description: "Task ID", Required: true},
		},
	))

	spec.AddPath("/projects/{id}/sdlc/features/{slug}/tasks/{taskId}/block", "post", withAuthAndParams(
		"Block task",
		"Marks a task as blocked.",
		"SDLC",
		"projects:execute",
		[]param{
			{Name: "id", In: "path", Description: "Project ID", Required: true},
			{Name: "slug", In: "path", Description: "Feature slug", Required: true},
			{Name: "taskId", In: "path", Description: "Task ID", Required: true},
		},
	))

	// Branch management
	spec.AddPath("/projects/{id}/sdlc/features/{slug}/branch", "post", withAuthAndParams(
		"Create branch",
		"Creates a feature branch and its manifest.",
		"SDLC",
		"projects:execute",
		[]param{
			{Name: "id", In: "path", Description: "Project ID", Required: true},
			{Name: "slug", In: "path", Description: "Feature slug", Required: true},
		},
	))

	spec.AddPath("/projects/{id}/sdlc/features/{slug}/branch", "get", withAuthAndParams(
		"Get branch status",
		"Returns branch status and merge checklist.",
		"SDLC",
		"projects:read",
		[]param{
			{Name: "id", In: "path", Description: "Project ID", Required: true},
			{Name: "slug", In: "path", Description: "Feature slug", Required: true},
		},
	))

	spec.AddPath("/projects/{id}/sdlc/features/{slug}/branch/sync", "post", withAuthAndParams(
		"Sync branch",
		"Syncs feature branch with base branch.",
		"SDLC",
		"projects:execute",
		[]param{
			{Name: "id", In: "path", Description: "Project ID", Required: true},
			{Name: "slug", In: "path", Description: "Feature slug", Required: true},
		},
	))

	// Merge and archive
	spec.AddPath("/projects/{id}/sdlc/features/{slug}/merge", "post", withAuthBodyAndParams(
		"Merge feature",
		"Merges a feature branch after all gates pass.",
		"SDLC",
		"projects:execute",
		[]param{
			{Name: "id", In: "path", Description: "Project ID", Required: true},
			{Name: "slug", In: "path", Description: "Feature slug", Required: true},
		},
		`{"strategy": "squash"}`,
		`{"status": "merged", "strategy": "squash"}`,
	))

	spec.AddPath("/projects/{id}/sdlc/features/{slug}/archive", "post", withAuthAndParams(
		"Archive feature",
		"Archives a released feature.",
		"SDLC",
		"projects:execute",
		[]param{
			{Name: "id", In: "path", Description: "Project ID", Required: true},
			{Name: "slug", In: "path", Description: "Feature slug", Required: true},
		},
	))

	// Query endpoints
	spec.AddPath("/projects/{id}/sdlc/query/blocked", "get", withAuthAndParams(
		"Query blocked features",
		"Returns all blocked features.",
		"SDLC",
		"projects:read",
		[]param{{Name: "id", In: "path", Description: "Project ID", Required: true}},
	))

	spec.AddPath("/projects/{id}/sdlc/query/ready", "get", withAuthAndParams(
		"Query ready features",
		"Returns features ready for work.",
		"SDLC",
		"projects:read",
		[]param{{Name: "id", In: "path", Description: "Project ID", Required: true}},
	))

	spec.AddPath("/projects/{id}/sdlc/query/needs-approval", "get", withAuthAndParams(
		"Query features needing approval",
		"Returns features awaiting approval.",
		"SDLC",
		"projects:read",
		[]param{{Name: "id", In: "path", Description: "Project ID", Required: true}},
	))

	// Orchestrator endpoints
	spec.AddPath("/projects/{id}/sdlc/execute", "post", withAuthBodyAndParams(
		"Execute action",
		"Executes the classifier's recommended next action.",
		"SDLC",
		"projects:execute",
		[]param{{Name: "id", In: "path", Description: "Project ID", Required: true}},
		`{"feature": "auth-flow", "provider": "claude"}`,
		`{"action": "CREATE_SPEC", "success": true, "output": "..."}`,
	))

	spec.AddPath("/projects/{id}/sdlc/resolve", "post", withAuthBodyAndParams(
		"Resolve blocker",
		"Resolves a feature blocker and re-classifies.",
		"SDLC",
		"projects:execute",
		[]param{{Name: "id", In: "path", Description: "Project ID", Required: true}},
		`{"feature": "auth-flow"}`,
		`{"action": "TRANSITION", "success": true, "output": "Feature unblocked"}`,
	))

	spec.AddPath("/projects/{id}/sdlc/commit", "post", withAuthBodyAndParams(
		"Commit changes",
		"Commits and optionally pushes changes in the project.",
		"SDLC",
		"projects:execute",
		[]param{{Name: "id", In: "path", Description: "Project ID", Required: true}},
		`{"feature": "auth-flow", "message": "feat: implement login", "push": true}`,
		`{"commit_sha": "abc123", "files_changed": ["handler.go"], "pushed": true}`,
	))
}

func registerBuildPaths(spec *api.OpenAPISpec) {
	spec.AddPath("/projects/{id}/builds", "post", withAuthBodyAndParams(
		"Start build",
		"Enqueues a build task for a project. The build will be picked up by an available worker.",
		"Builds",
		"projects:execute",
		[]param{{Name: "id", In: "path", Description: "Project ID", Required: true}},
		`{
  "prompt": "Build a landing page with Next.js and Tailwind CSS",
  "template": "nextjs-landing",
  "auto_commit": true,
  "auto_push": true,
  "callback_url": "https://example.com/webhook"
}`,
		`{
  "task_id": "task-abc123",
  "project_id": "my-project",
  "status": "pending",
  "status_url": "/builds/task-abc123"
}`,
	))

	spec.AddPath("/projects/{id}/builds", "get", withAuthAndParams(
		"List builds",
		"Returns build history for a project.",
		"Builds",
		"projects:read",
		[]param{{Name: "id", In: "path", Description: "Project ID", Required: true}},
	))

	spec.AddPath("/builds/{taskId}", "get", withAuthAndParams(
		"Get build status",
		"Returns the status and result of a specific build.",
		"Builds",
		"projects:read",
		[]param{{Name: "taskId", In: "path", Description: "Build task ID", Required: true}},
	))

	spec.AddPath("/project/create-and-build", "post", withAuthAndBody(
		"Create project and build",
		`Creates a new project and immediately enqueues a build task.

Combines project creation (git repo, DNS, CI activation) with build submission in a single call.`,
		"Builds",
		"admin",
		`{
  "name": "my-landing-page",
  "description": "Landing page for product launch",
  "template": "nextjs-landing",
  "prompt": "Build a modern landing page with hero, features, and CTA sections",
  "auto_commit": true,
  "auto_push": true
}`,
		`{
  "project_id": "my-landing-page",
  "name": "my-landing-page",
  "domain": "my-landing-page.threesix.ai",
  "url": "https://my-landing-page.threesix.ai",
  "git": {
    "owner": "jordan",
    "name": "my-landing-page",
    "clone_http": "https://git.threesix.ai/jordan/my-landing-page.git"
  },
  "task_id": "task-abc123",
  "status": "pending",
  "status_url": "/builds/task-abc123"
}`,
	))
}
