/**
 * Policy Engine — 权限策略引擎
 *
 * 三级权限模型：Read / Write / External Action
 *
 * @see docs/生产级通用 AI Agent 智能体桌面应用：完整设计与构建指南.html — 第十章
 */

export enum PermissionLevel {
  READ = 'read',
  WRITE = 'write',
  EXTERNAL_ACTION = 'external',
}

export interface PermissionPolicy {
  toolName: string;
  requiredLevel: PermissionLevel;
  allowedPatterns?: RegExp[];
  deniedPatterns?: RegExp[];
  maxFrequency?: number;
  requireConfirmation?: boolean;
}

export const DEFAULT_POLICIES: PermissionPolicy[] = [
  { toolName: 'read_file', requiredLevel: PermissionLevel.READ, deniedPatterns: [/\/etc\//, /\/proc\//] },
  { toolName: 'web_search', requiredLevel: PermissionLevel.READ, maxFrequency: 10 },
  { toolName: 'list_directory', requiredLevel: PermissionLevel.READ },
  { toolName: 'search_files', requiredLevel: PermissionLevel.READ },
  { toolName: 'memory_search', requiredLevel: PermissionLevel.READ },
  { toolName: 'write_file', requiredLevel: PermissionLevel.WRITE, deniedPatterns: [/\/etc\//, /\/proc\//, /\/System\//], requireConfirmation: true, maxFrequency: 5 },
  { toolName: 'memory_store', requiredLevel: PermissionLevel.WRITE },
  { toolName: 'run_command', requiredLevel: PermissionLevel.EXTERNAL_ACTION, requireConfirmation: true, maxFrequency: 3 },
  { toolName: 'web_extract', requiredLevel: PermissionLevel.READ },
];

export class PolicyEngine {
  private policies: Map<string, PermissionPolicy> = new Map();

  constructor(customPolicies: PermissionPolicy[] = []) {
    for (const policy of DEFAULT_POLICIES) {
      this.policies.set(policy.toolName, policy);
    }
    for (const policy of customPolicies) {
      this.policies.set(policy.toolName, policy);
    }
  }

  checkAuthorization(toolName: string, args: Record<string, unknown>): {
    authorized: boolean;
    reason?: string;
    level: PermissionLevel;
    requiresConfirmation: boolean;
  } {
    const policy = this.policies.get(toolName);

    if (!policy) {
      return {
        authorized: false,
        reason: `No policy configured for tool: ${toolName}`,
        level: PermissionLevel.EXTERNAL_ACTION,
        requiresConfirmation: true,
      };
    }

    if (policy.deniedPatterns) {
      const argsStr = JSON.stringify(args);
      for (const pattern of policy.deniedPatterns) {
        if (pattern.test(argsStr)) {
          return {
            authorized: false,
            reason: `Arguments match denied pattern: ${pattern.source}`,
            level: policy.requiredLevel,
            requiresConfirmation: false,
          };
        }
      }
    }

    return {
      authorized: true,
      level: policy.requiredLevel,
      requiresConfirmation: policy.requireConfirmation ?? false,
    };
  }
}
