package server

import (
	"github.com/mem9-ai/drive9/pkg/openapi"
)

// This file holds the hand-written schema blobs referenced by the endpoint
// registry (openapi_registry.go). They cover response/request shapes that
// have no named Go struct (anonymous decode structs, inline maps) or that
// wrap reflected types in a stable component (e.g. backends list).

// Common response bodies.
var (
	statusOKResponse = openapi.Raw("", map[string]any{
		"type":       "object",
		"properties": map[string]any{"status": map[string]any{"type": "string"}},
		"required":   []string{"status"},
	})
	revisionResponse = openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"status":   map[string]any{"type": "string"},
			"revision": map[string]any{"type": "integer", "format": "int64"},
		},
		"required": []string{"status", "revision"},
	})
	appendLogResponse = openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"revision":   map[string]any{"type": "integer", "format": "int64"},
			"size_bytes": map[string]any{"type": "integer", "format": "int64"},
		},
		"required": []string{"revision", "size_bytes"},
	})
	fsPostResponse = openapi.Raw("", map[string]any{
		"oneOf": []any{
			statusOKResponse.Raw,
			appendLogResponse.Raw,
		},
	})
	fsActionErrorRef = ref(openapi.Raw("FilesystemActionError", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"error": map[string]any{"type": "string"},
			"code": map[string]any{
				"type":        "string",
				"description": "Present for append-log domain errors, including append_log_conflict, append_log_rebased, append_log_unsupported, append_log_invalid_request, and append_log_too_large. Only append_log_rebased permits re-stat and retry of the unchanged tail. Other actions and authentication errors may omit this field.",
			},
		},
		"required": []string{"error"},
	}))
	statusMapResponse  = openapi.Raw("", map[string]any{"type": "object", "additionalProperties": map[string]any{"type": "string"}})
	statusOKRef        = ref(statusOKResponse)
	revisionRef        = ref(revisionResponse)
	fsPostResponseRef  = ref(fsPostResponse)
	statusMapRef       = ref(statusMapResponse)
	tenantNamespaceRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"tenant_id":    map[string]any{"type": "string"},
			"namespace_id": map[string]any{"type": "string"},
		},
		"required": []string{"tenant_id", "namespace_id"},
	}))
	backendsListRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"backends": map[string]any{
				"type":  "array",
				"items": openapiRef("server.adminObjectBackendView"),
			},
		},
		"required": []string{"backends"},
	}))
	objectBackendDeleteRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"id":     map[string]any{"type": "string"},
			"status": map[string]any{"type": "string"},
		},
		"required": []string{"id", "status"},
	}))
	provisionAcceptedRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"tenant_id":       map[string]any{"type": "string"},
			"api_key":         map[string]any{"type": "string"},
			"status":          map[string]any{"type": "string"},
			"cloud_provider":  map[string]any{"type": "string"},
			"region":          map[string]any{"type": "string"},
			"organization_id": map[string]any{"type": "string"},
		},
		"required": []string{"tenant_id", "api_key", "status"},
	}))
	secretsListRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"secrets": map[string]any{"type": "array", "items": openapiRef("vault.Secret")},
		},
		"required": []string{"secrets"},
	}))
	auditEventsRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"events": map[string]any{"type": "array", "items": openapiRef("vault.AuditEvent")},
		},
		"required": []string{"events"},
	}))
	tokenIssueRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"token":      map[string]any{"type": "string"},
			"token_id":   map[string]any{"type": "string"},
			"expires_at": map[string]any{"type": "string", "format": "date-time"},
		},
		"required": []string{"token", "token_id", "expires_at"},
	}))
	grantIssueRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"token":      map[string]any{"type": "string"},
			"grant_id":   map[string]any{"type": "string"},
			"expires_at": map[string]any{"type": "string", "format": "date-time"},
			"scope":      map[string]any{"type": "array", "items": map[string]any{"type": "string"}},
			"perm":       map[string]any{"type": "string"},
		},
		"required": []string{"token", "grant_id", "expires_at", "scope", "perm"},
	}))
	readValueRef = ref(openapi.Raw("", map[string]any{
		"type":                 "object",
		"additionalProperties": map[string]any{"type": "string"},
	}))
	secretsNamesRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"secrets": map[string]any{"type": "array", "items": map[string]any{"type": "string"}},
		},
		"required": []string{"secrets"},
	}))
	// Vault management anonymous request bodies.
	vaultSecretCreateRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"name":        map[string]any{"type": "string"},
			"secret_type": map[string]any{"type": "string"},
			"fields":      map[string]any{"type": "object", "additionalProperties": map[string]any{"type": "string"}},
			"created_by":  map[string]any{"type": "string"},
		},
		"required": []string{"name", "fields"},
	}))
	vaultSecretUpdateRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"fields":     map[string]any{"type": "object", "additionalProperties": map[string]any{"type": "string"}},
			"updated_by": map[string]any{"type": "string"},
		},
		"required": []string{"fields"},
	}))
	vaultTokenIssueRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"agent_id":    map[string]any{"type": "string"},
			"task_id":     map[string]any{"type": "string"},
			"scope":       map[string]any{"type": "array", "items": map[string]any{"type": "string"}},
			"ttl_seconds": map[string]any{"type": "integer", "format": "int64"},
		},
	}))
	vaultGrantIssueRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"agent":       map[string]any{"type": "string"},
			"scope":       map[string]any{"type": "array", "items": map[string]any{"type": "string"}},
			"perm":        map[string]any{"type": "string"},
			"ttl_seconds": map[string]any{"type": "integer", "format": "int64"},
			"label_hint":  map[string]any{"type": "string"},
		},
		"required": []string{"agent", "ttl_seconds"},
	}))
	vaultRevokeRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"revoked_by": map[string]any{"type": "string"},
			"reason":     map[string]any{"type": "string"},
		},
	}))
	credentialsBodyRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"public_key":  map[string]any{"type": "string"},
			"private_key": map[string]any{"type": "string"},
		},
	}))
	// Anonymous decode bodies that handlers define inline.
	patchBodyRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"new_size":          map[string]any{"type": "integer", "format": "int64"},
			"dirty_parts":       map[string]any{"type": "array", "items": map[string]any{"type": "integer", "format": "int64"}},
			"part_size":         map[string]any{"type": "integer", "format": "int64"},
			"expected_revision": map[string]any{"type": "integer", "format": "int64"},
		},
		"required": []string{"new_size", "dirty_parts"},
	}))
	appendBodyRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"append_size":       map[string]any{"type": "integer", "format": "int64"},
			"part_size":         map[string]any{"type": "integer", "format": "int64"},
			"expected_revision": map[string]any{"type": "integer", "format": "int64"},
		},
		"required": []string{"append_size"},
	}))
	// fsPostBodyRef is the action-specific body union of POST /v1/fs/{path}:
	// append={append_size,...}, chmod={mode}, symlink={target},
	// setmeta={tags?, description?}. Other actions (copy/rename/mkdir/create/
	// hardlink) take no body.
	fsPostBodyRef = ref(openapi.Raw("", map[string]any{
		"oneOf": []any{
			(*appendBodyRef).Raw,
			(*chmodBodyRef).Raw,
			(*symlinkBodyRef).Raw,
			(*setmetaBodyRef).Raw,
		},
	}))
	chmodBodyRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"mode": map[string]any{"type": "integer", "format": "int64"},
		},
		"required": []string{"mode"},
	}))
	symlinkBodyRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"target": map[string]any{"type": "string"},
		},
		"required": []string{"target"},
	}))
	// setmetaBodyRef has no required fields on purpose: an empty object is a
	// valid body shape that the handler rejects with 400 (nothing to update).
	// additionalProperties is closed so oneOf stays unambiguous against the
	// other fsPostBodyRef variants.
	setmetaBodyRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"tags": map[string]any{
				"type":                 "object",
				"additionalProperties": map[string]any{"type": "string"},
			},
			"description": map[string]any{"type": "string"},
		},
		"additionalProperties": false,
	}))
	uploadInitiateBodyRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"path":              map[string]any{"type": "string"},
			"total_size":        map[string]any{"type": "integer", "format": "int64"},
			"part_checksums":    map[string]any{"type": "array", "items": map[string]any{"type": "string"}},
			"expected_revision": map[string]any{"type": "integer", "format": "int64"},
			"description":       map[string]any{"type": "string"},
		},
		"required": []string{"path", "total_size", "part_checksums"},
	}))
	v2UploadInitiateBodyRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"path":              map[string]any{"type": "string"},
			"total_size":        map[string]any{"type": "integer", "format": "int64"},
			"expected_revision": map[string]any{"type": "integer", "format": "int64"},
			"description":       map[string]any{"type": "string"},
		},
		"required": []string{"path", "total_size"},
	}))
	presignPartBodyRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"part_number": map[string]any{"type": "integer", "format": "int64"},
			"checksum":    openapiRef("backend.PresignChecksum"),
		},
		"required": []string{"part_number"},
	}))
	presignBatchBodyRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"parts": map[string]any{"type": "array", "items": openapiRef("backend.PresignPartEntry")},
		},
		"required": []string{"parts"},
	}))
	presignBatchRespRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"parts": map[string]any{"type": "array", "items": openapiRef("s3client.UploadPartURL")},
		},
		"required": []string{"parts"},
	}))
	resumeBodyRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"part_checksums": map[string]any{"type": "array", "items": map[string]any{"type": "string"}},
		},
	}))
	sqlBodyRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"query": map[string]any{"type": "string"},
		},
		"required": []string{"query"},
	}))
	sqlRespRef = ref(openapi.Raw("", map[string]any{
		"type": "array",
		"items": map[string]any{
			"type":                 "object",
			"additionalProperties": map[string]any{},
		},
	}))
	migrationEventBodyRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"tenant_id":              map[string]any{"type": "string"},
			"event_id":               map[string]any{"type": "string"},
			"emitted_at":             map[string]any{"type": "string", "format": "date-time"},
			"phase":                  map[string]any{"type": "string", "enum": []string{"DUAL_WRITE_REPAIRING"}},
			"round_id":               map[string]any{"type": "string"},
			"first_seen_at":          map[string]any{"type": "string", "format": "date-time"},
			"job_id":                 map[string]any{"type": "string"},
			"volume_id":              map[string]any{"type": "string"},
			"node_name":              map[string]any{"type": "string"},
			"pod_name":               map[string]any{"type": "string"},
			"space_id":               map[string]any{"type": "string"},
			"source_path":            map[string]any{"type": "string"},
			"target_path":            map[string]any{"type": "string"},
			"source_version_token":   map[string]any{"type": "string"},
			"source_checksum_sha256": map[string]any{"type": "string"},
			"resource_id":            map[string]any{"type": "string"},
			"drive9_checksum_sha256": map[string]any{"type": "string"},
			"operation":              map[string]any{"type": "string", "enum": []string{"create", "update"}},
			"result":                 map[string]any{"type": "string", "enum": []string{"success", "conflict", "failure"}},
			"error_class":            map[string]any{"type": "string"},
			"cas_attempt":            map[string]any{"type": "integer", "format": "int64"},
			"grace_seconds":          map[string]any{"type": "integer", "format": "int64"},
			"size":                   map[string]any{"type": "integer", "format": "int64"},
			"mtime":                  map[string]any{"type": "integer", "format": "int64"},
			"revision":               map[string]any{"type": "integer", "format": "int64"},
			"expected_revision":      map[string]any{"type": "integer", "format": "int64"},
			"latency_ms":             map[string]any{"type": "integer", "format": "int64"},
		},
		"required": []string{
			"event_id", "emitted_at", "phase", "round_id", "first_seen_at", "job_id", "volume_id",
			"node_name", "pod_name", "space_id", "source_path", "target_path", "source_version_token",
			"source_checksum_sha256", "resource_id", "drive9_checksum_sha256", "operation", "result",
			"error_class", "cas_attempt", "grace_seconds", "size", "mtime", "revision",
			"expected_revision", "latency_ms",
		},
	}))
	layersListRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"layers": map[string]any{"type": "array", "items": openapiRef("server.fsLayerResponse")},
		},
		"required": []string{"layers"},
	}))
	layerChainRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"chain": map[string]any{"type": "array", "items": map[string]any{"type": "object"}},
		},
		"required": []string{"chain"},
	}))
	layerDiffRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"entries": map[string]any{"type": "array", "items": openapiRef("server.fsLayerEntryResponse")},
		},
		"required": []string{"entries"},
	}))
	layerEventsRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"events": map[string]any{"type": "array", "items": openapiRef("server.fsLayerEventResponse")},
		},
		"required": []string{"events"},
	}))
	layerAbandonRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"status":   map[string]any{"type": "string"},
			"layer_id": map[string]any{"type": "string"},
		},
		"required": []string{"status", "layer_id"},
	}))
	gitWorkspacesListRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"workspaces": map[string]any{"type": "array", "items": openapiRef("server.gitWorkspaceResponse")},
		},
		"required": []string{"workspaces"},
	}))
	gitTreeListRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"nodes": map[string]any{"type": "array", "items": openapiRef("server.gitTreeNodeResponse")},
		},
		"required": []string{"nodes"},
	}))
	gitTreeReplaceRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"status": map[string]any{"type": "string"},
			"count":  map[string]any{"type": "integer", "format": "int64"},
		},
		"required": []string{"status", "count"},
	}))
	gitPacksListRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"packs": map[string]any{"type": "array", "items": openapiRef("server.gitObjectPackResponse")},
		},
		"required": []string{"packs"},
	}))
	gitOverlayListRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"entries": map[string]any{"type": "array", "items": openapiRef("server.gitOverlayEntryResponse")},
		},
		"required": []string{"entries"},
	}))
	uploadsListRespRef = ref(openapi.Raw("", map[string]any{
		"type": "object",
		"properties": map[string]any{
			"uploads": map[string]any{
				"type": "array",
				"items": map[string]any{
					"type": "object",
					"properties": map[string]any{
						"upload_id":   map[string]any{"type": "string"},
						"path":        map[string]any{"type": "string"},
						"total_size":  map[string]any{"type": "integer", "format": "int64"},
						"parts_total": map[string]any{"type": "integer", "format": "int64"},
						"status":      map[string]any{"type": "string"},
						"created_at":  map[string]any{"type": "string", "format": "date-time"},
						"expires_at":  map[string]any{"type": "string", "format": "date-time"},
					},
					"required": []string{"upload_id", "path", "total_size", "parts_total", "status", "created_at", "expires_at"},
				},
			},
		},
		"required": []string{"uploads"},
	}))
	gitWorkspaceUnionRef = ref(openapi.Raw("", map[string]any{
		"oneOf": []any{
			openapiRef("server.gitWorkspaceResponse"),
			(*gitWorkspacesListRef).Raw,
		},
	}))
	gitOverlayUnionRef = ref(openapi.Raw("", map[string]any{
		"oneOf": []any{
			openapiRef("server.gitOverlayEntryResponse"),
			(*gitOverlayListRef).Raw,
		},
	}))
	findRespRef = ref(openapi.Raw("", map[string]any{
		"type":  "array",
		"items": openapiRef("datastore.SearchResult"),
	}))
	listRespRef = ref(openapi.Raw("", map[string]any{
		"type":  "array",
		"items": openapiRef("server.fsListResponseEntry"),
	}))
	grepRespRef = ref(openapi.Raw("", map[string]any{
		"type": "array",
		"items": map[string]any{
			"type":                 "object",
			"additionalProperties": map[string]any{},
		},
	}))
	// fsJsonRespRef is the JSON union returned by GET /v1/fs/{path} action
	// selectors: stat=1, list=1, grep=<q>, find=1.
	fsJsonRespRef = ref(openapi.Raw("", map[string]any{
		"oneOf": []any{
			openapiRef("server.fsStatMetadataResponse"),
			(*listRespRef).Raw,
			(*grepRespRef).Raw,
			(*findRespRef).Raw,
		},
	}))
	fsReadRespRef = ref(openapi.Raw("", map[string]any{"type": "string", "format": "binary"}))
)
