package middleware

import (
	"log/slog"
	"net/http"

	"security-center-backend/internal/pkg/response"

	"github.com/gin-gonic/gin"
)

// agentAllowedRoutes 是 Agent 调用(auth_method=agent)允许访问的端点白名单。
// key 为 "METHOD /path" 形式, 其中 path 是 Gin 路由模式(c.FullPath() 返回的形态),
// 路径参数名与路由注册处保持一致(CAASM 用 :id, Vuln 用 :public_id)。
// GET 清单与 docs/issue/001-mcp-tool-selection.md §3 的 35 个端点一一对应(CAASM 25 + Vuln 10),
// 另加 P3-T5 上线的 /api/v1/openapi.json(裸 JSON 输出), 共 36 条;
// iteration-002 P1-T4 新增 6 条漏洞写路由(plan §3.3, 决策 9), 共 42 条;
// 再加 whoami 身份自描述端点(37 GET), 共 43 条。
// 不开放 Claim(认领)路由, 不开放任何 DELETE。
var agentAllowedRoutes = map[string]struct{}{
	// 身份自描述 GET(1): 任何认证 agent Key 可达(不挂 manage_own_keys 权限)
	"GET /api/v1/agent/whoami": {},
	// CAASM GET(25)
	"GET /api/v1/caasm/assets":                   {},
	"GET /api/v1/caasm/ip-assets":                {},
	"GET /api/v1/caasm/assets/:id":               {},
	"GET /api/v1/caasm/assets/:id/tags":          {},
	"GET /api/v1/caasm/assets/services":          {},
	"GET /api/v1/caasm/assets/environments":      {},
	"GET /api/v1/caasm/ports":                    {},
	"GET /api/v1/caasm/ports/:id":                {},
	"GET /api/v1/caasm/ports/stats":              {},
	"GET /api/v1/caasm/ports/high-risk":          {},
	"GET /api/v1/caasm/assets/ports/search":      {},
	"GET /api/v1/caasm/dns-records":              {},
	"GET /api/v1/caasm/dns-records/:id/comments": {},
	"GET /api/v1/caasm/domains":                  {},
	"GET /api/v1/caasm/domains/stats":            {},
	"GET /api/v1/caasm/domains/registrars":       {},
	"GET /api/v1/caasm/relationships/graph":      {},
	"GET /api/v1/caasm/cloud-accounts":           {},
	"GET /api/v1/caasm/cloud-accounts/:id":       {},
	"GET /api/v1/caasm/cloud-accounts/:id/jobs":  {},
	"GET /api/v1/caasm/sync-jobs":                {},
	"GET /api/v1/caasm/sync-jobs/:id":            {},
	"GET /api/v1/caasm/sync-jobs/:id/events":     {},
	"GET /api/v1/caasm/api-assets":               {},
	"GET /api/v1/caasm/api-assets/config/active": {},
	// Vuln GET(10)
	"GET /api/v1/vulnerabilities":                               {},
	"GET /api/v1/vulnerabilities/:public_id":                    {},
	"GET /api/v1/vulnerabilities/:public_id/events":             {},
	"GET /api/v1/vulnerabilities/:public_id/comments":           {},
	"GET /api/v1/vulnerabilities/:public_id/viewers/candidates": {},
	"GET /api/v1/vulnerability-tags":                            {},
	"GET /api/v1/vulnerability-tags/stats":                      {},
	"GET /api/v1/vulnerability-types":                           {},
	"GET /api/v1/vulnerability-sources":                         {},
	"GET /api/v1/vulnerability-discovery-channels":              {},
	// OpenAPI 文档 GET(1): P3-T5 上线的裸 JSON 端点
	"GET /api/v1/openapi.json": {},
	// Vuln 写(6): iteration-002 P1-T4, 与 handler.RegisterRoutes/RegisterRestrictedRoutes 注册模式一致
	"POST /api/v1/vulnerabilities":                       {}, // 提交
	"PUT /api/v1/vulnerabilities/:public_id":             {}, // 编辑
	"POST /api/v1/vulnerabilities/:public_id/transition": {}, // 复测/验证/关闭/重开
	"POST /api/v1/vulnerabilities/:public_id/comments":   {}, // 评论
	"POST /api/v1/vulnerabilities/uploads":               {}, // 附件预签名
	"POST /api/v1/vulnerabilities/uploads/confirm":       {}, // 附件确认
}

func agentAllowedRoute(method, fullPath string) bool {
	_, ok := agentAllowedRoutes[method+" "+fullPath]
	return ok
}

// AgentRouteAllowlist: Agent 调用(auth_method=agent)只放行白名单内的 method+path; 人类 JWT 调用直通。
func AgentRouteAllowlist() gin.HandlerFunc {
	return func(c *gin.Context) {
		if c.GetString("auth_method") != "agent" {
			c.Next()
			return
		}
		if agentAllowedRoute(c.Request.Method, c.FullPath()) {
			c.Next()
			return
		}
		keyID, _ := c.Get("api_key_id")
		slog.Warn("agent route blocked by allowlist",
			"method", c.Request.Method,
			"path", c.FullPath(),
			"api_key_id", keyID,
		)
		response.Error(c, http.StatusForbidden, "agent not allowed on this route")
		c.Abort()
	}
}
