// lib/policy.js — Policy loader and rule engine

const DEFAULT_POLICY = {
  version: 1,
  rules: [
    {
      id: 'rule_allowed_domains',
      type: 'allowed_domains',
      enabled: true,
      params: {
        domains: ['github.com', 'claude.ai', 'api.openai.com', 'chatgpt.com', 'cursor.sh']
      }
    },
    {
      id: 'rule_allowed_operations',
      type: 'allowed_operations',
      enabled: true,
      params: {
        operations: ['read', 'chat', 'search', 'code_generation', 'page_visit']
      }
    },
    {
      id: 'rule_disallowed_tools',
      type: 'disallowed_tools',
      enabled: true,
      params: {
        tools: ['eval', 'exec', 'shell', 'system', 'rm', 'sudo', 'chmod']
      }
    },
    {
      id: 'rule_permission_change',
      type: 'permission_change',
      enabled: true,
      params: {}
    },
    {
      id: 'rule_redundant_rate',
      type: 'redundant_rate',
      enabled: true,
      params: {
        max_per_minute: 10
      }
    },
    {
      id: 'rule_task_scope',
      type: 'task_scope',
      enabled: false,
      params: {
        task_keywords: []
      }
    }
  ]
};

export async function loadPolicy() {
  try {
    const result = await chrome.storage.local.get(['policy']);
    if (result.policy) return result.policy;
    await chrome.storage.local.set({ policy: DEFAULT_POLICY });
    return DEFAULT_POLICY;
  } catch (err) {
    console.error('Policy load error:', err);
    return DEFAULT_POLICY;
  }
}

export async function savePolicy(policy) {
  policy.version = (policy.version || 0) + 1;
  await chrome.storage.local.set({ policy });
  return policy;
}

export function checkPolicy(event, policy) {
  const rules = policy?.rules || [];
  let outcome = 'allowed';
  let severity = 'info';
  let ruleId = null;

  for (const rule of rules) {
    if (!rule.enabled) continue;
    const result = evaluateRule(event, rule);
    if (result.violation) {
      outcome = 'violation';
      severity = result.severity;
      ruleId = rule.id;
      break;
    }
    if (result.warning) {
      if (outcome !== 'violation') {
        outcome = 'warning';
        severity = result.severity;
        ruleId = rule.id;
      }
    }
  }

  return { outcome, severity, ruleId };
}

function evaluateRule(event, rule) {
  switch (rule.type) {
    case 'allowed_domains': return evaluateAllowedDomains(event, rule);
    case 'allowed_operations': return evaluateAllowedOperations(event, rule);
    case 'disallowed_tools': return evaluateDisallowedTools(event, rule);
    case 'permission_change': return evaluatePermissionChange(event, rule);
    case 'redundant_rate': return { violation: false };
    case 'task_scope': return evaluateTaskScope(event, rule);
    default: return { violation: false };
  }
}

function evaluateAllowedDomains(event, rule) {
  const allowed = rule.params?.domains || [];
  if (event.type === 'api_call' || event.type === 'tool_use') {
    const url = event.target || event.url || '';
    try {
      const hostname = new URL(url).hostname;
      const isAllowed = allowed.some(d => hostname.includes(d));
      if (!isAllowed) {
        return { violation: true, severity: 'high' };
      }
    } catch { /* invalid URL */ }
  }
  return { violation: false };
}

function evaluateAllowedOperations(event, rule) {
  const allowed = rule.params?.operations || [];
  const opType = event.type || '';
  const isAllowed = allowed.some(op => opType.includes(op));
  if (!isAllowed && (event.type === 'api_call' || event.type === 'tool_use')) {
    return { violation: true, severity: 'medium' };
  }
  return { violation: false };
}

function evaluateDisallowedTools(event, rule) {
  const disallowed = rule.params?.tools || [];
  const toolName = event.tool || '';
  if (disallowed.some(dt => toolName.toLowerCase().includes(dt.toLowerCase()))) {
    return { violation: true, severity: 'critical' };
  }
  return { violation: false };
}

function evaluatePermissionChange(event, rule) {
  const context = (event.context || '') + (event.target || '') + (event.url || '');
  const keywords = ['permission', 'grant', 'access control', 'role', 'privilege', 'acl', 'rbac'];
  if (keywords.some(kw => context.toLowerCase().includes(kw))) {
    return { violation: true, severity: 'critical' };
  }
  return { violation: false };
}

function evaluateTaskScope(event, rule) {
  const keywords = rule.params?.task_keywords || [];
  if (keywords.length === 0) return { violation: false };
  const context = (event.context || '') + (event.target || '');
  const onTask = keywords.some(kw => context.toLowerCase().includes(kw.toLowerCase()));
  if (!onTask && event.type === 'tool_use') {
    return { violation: true, severity: 'low' };
  }
  return { violation: false };
}
