package middleware

import (
	"slices"
	"strings"
)

var agentAllowedScopePrefixes = []string{
	"caasm:view_", "vuln:view_",
	// Phase 扩展时再加 scan:view_ 等
}

// 显式放行的写 scope(plan 002 决策 1, 003 新增 vuln:submit_findings): 逐枚列举, 不开前缀, 防止新写权限被误放给 Agent
var agentAllowedWriteScopes = []string{
	"vuln:edit_details",
	"vuln:request_retest",
	"vuln:close_findings",
	"vuln:submit_findings",
}

// 显式排除: 前缀命中但属敏感/高危权限, 永远不放给 Agent(plan 002 决策 5)。
// denylist 优先于一切放行规则。
var agentScopeDenylist = []string{
	"vuln:view_sensitive_details",
	"vuln:edit_sensitive_details",
	"vuln:manage_findings",
	"vuln:authorize_viewers",
	"vuln:assign_owner",
}

func scopeAllowedForAgent(perms []string) bool {
	for _, p := range perms {
		if slices.Contains(agentScopeDenylist, p) {
			return false
		}
		ok := slices.Contains(agentAllowedWriteScopes, p)
		for _, prefix := range agentAllowedScopePrefixes {
			if strings.HasPrefix(p, prefix) {
				ok = true
				break
			}
		}
		if !ok {
			return false
		}
	}
	return len(perms) > 0
}

// ScopeSubsetOfUserAndAgentAllowed 双重校验: reqPerms 必须 ⊆ (用户已有权限 ∩ agent 白名单)。
// 即使白名单将来放宽, 用户也无法给自己发不具备的权限——纵深防御。
func ScopeSubsetOfUserAndAgentAllowed(reqPerms, userPerms []string) bool {
	userSet := make(map[string]struct{}, len(userPerms))
	for _, p := range userPerms {
		userSet[p] = struct{}{}
	}
	for _, p := range reqPerms {
		if !scopeAllowedForAgent([]string{p}) {
			return false
		} // 白名单(含 denylist)
		if _, ok := userSet[p]; !ok {
			return false
		} // 用户真有此权限
	}
	return len(reqPerms) > 0
}
