package permission

import (
	"context"
)

// PermissionChecker 对外暴露的权限检查接口
type PermissionChecker struct {
	jenkinsPermService *JenkinsPermissionService
	projectPermService *ProjectPermissionService
	userDao            *UserDao
	permissionCache    *PermissionCache    // L1 内存缓存
	permissionCacheDao *PermissionCacheDao // L2 DB 缓存
}

// CheckJenkinsPermission 检查 Jenkins 分支权限
// 层级继承：Org -> Repo -> Branch
func (p *PermissionChecker) CheckJenkinsPermission(
	ctx context.Context,
	userID int64,
	org, repo, branch string,
	requireBuild bool,
) (bool, error) {
	// 1. 检查是否为 SuperAdmin（直接放行）
	user, err := p.userDao.GetByID(userID)
	if err != nil {
		return false, err
	}
	if user.Role == "superadmin" {
		return true, nil
	}

	// 2. 先查 L1 内存缓存
	cacheKey := p.buildCacheKey(userID, org, repo, branch)
	if cached, ok := p.permissionCache.Get(cacheKey); ok {
		return p.evaluatePermission(cached, requireBuild), nil
	}

	// 3. 再查 L2 DB 缓存 (user_permission_caches)
	if cached, err := p.permissionCacheDao.GetUserPermissionTree(userID); err == nil {
		// 从缓存树中查找权限
		if perm := cached.FindPermission(org, repo, branch); perm != nil {
			p.permissionCache.Set(cacheKey, perm) // 回填 L1
			return p.evaluatePermission(perm, requireBuild), nil
		}
	}

	// 4. 层级权限检查
	return p.jenkinsPermService.CheckHierarchicalPermission(
		userID, org, repo, branch, requireBuild,
	)
}

// CheckHierarchicalPermission 层级权限检查逻辑
// 优先级：Branch > Repo > Org
func (s *JenkinsPermissionService) CheckHierarchicalPermission(
	userID int64,
	org, repo, branch string,
	requireBuild bool,
) (bool, error) {
	// 先查 Branch 级别
	perm, err := s.jenkinsAclDao.FindPermission(userID, org, repo, branch)
	if err == nil && perm.CanView {
		if !requireBuild || perm.CanBuild {
			return true, nil
		}
	}

	// 再查 Repo 级别（branch 为空）
	perm, err = s.jenkinsAclDao.FindPermission(userID, org, repo, "")
	if err == nil && perm.CanView {
		if !requireBuild || perm.CanBuild {
			return true, nil
		}
	}

	// 最后查 Org 级别（repo 和 branch 都为空）
	perm, err = s.jenkinsAclDao.FindPermission(userID, org, "", "")
	if err == nil && perm.CanView {
		if !requireBuild || perm.CanBuild {
			return true, nil
		}
	}

	return false, nil
}

// CheckProjectModulePermission 检查项目模块权限
func (p *PermissionChecker) CheckProjectModulePermission(
	ctx context.Context,
	userID int64,
	userRole string,
	projectID string,
	moduleCode string,
	permissionType string, // "view" or "export"
) (bool, error) {
	// 1. SuperAdmin 拥有所有权限
	if userRole == "superadmin" {
		return true, nil
	}

	// 2. authorization_info 模块仅 SuperAdmin 可访问
	if moduleCode == "authorization_info" {
		return false, nil
	}

	// 3. 检查是否为项目填写人（自动拥有非授权模块的 view 权限）
	if permissionType == "view" {
		fillerID, err := p.projectInfoQuerier.GetProjectFillerID(ctx, projectID)
		if err == nil && fillerID == userID {
			return true, nil
		}
	}

	// 4. 查询 project_acls 表
	return p.projectPermService.CheckModulePermission(
		userID, projectID, moduleCode, permissionType,
	)
}

// InvalidateCache 权限变更时清除缓存
func (p *PermissionChecker) InvalidateCache(userID int64) error {
	// 清除 L1 内存缓存
	p.permissionCache.DeleteByUser(userID)

	// 清除 L2 DB 缓存 (user_permission_caches)
	return p.permissionCacheDao.DeleteUserPermissionCache(userID)
}

// 权限缓存管理
// L1: 内存缓存 permissionCache (进程内高速缓存)
// L2: 数据库表 user_permission_caches (JSON格式存储权限树)
//
// 缓存失效时机：
// 1. 权限分配 (POST /api/permissions/jenkins/assign)
// 2. 权限拷贝 (POST /api/permissions/jenkins/copy)
// 3. 权限撤销 (POST /api/permissions/projects/revoke)
