// Permission Drift Detector - Detects new permissions added on extension update
// Browser Techniques Line 187: Permission drift on update
// Updates add risky permissions

import { BaseDetector } from '../base-detector.js';

export class PermissionDriftDetector extends BaseDetector {
  constructor(config = {}) {
    super({
      name: 'permission-drift',
      category: 'malicious-extensions',
      version: '1.0.0',
      description: 'Detects permission drift when extensions update',
      weight: 3,
      severity: 'high',
      ...config
    });
  }

  async detect(target, ruleRegistry) {
    const findings = [];

    // This detector requires extension update event data
    const oldPermissions = target.oldPermissions || [];
    const newPermissions = target.newPermissions || [];
    const addedPermissions = target.addedPermissions || [];
    const removedPermissions = target.removedPermissions || [];
    const extensionId = target.extensionId;
    const extensionName = target.extensionName;

    if (addedPermissions.length === 0 && removedPermissions.length === 0) {
      return this.createResult(false, [], 0);
    }

    const rules = ruleRegistry.getRules('malicious-extensions', 'permission-drift');

    if (!rules) {
      return this.createResult(false, [], 0);
    }

    // 1. Detect high-risk permission additions
    const highRiskAdded = addedPermissions.filter(perm =>
      (rules.highRiskPermissions || []).includes(perm)
    );

    if (highRiskAdded.length > 0) {
      findings.push(this.createFinding({
        pattern: 'high-risk-permission-added',
        matched: highRiskAdded.join(', '),
        description: `Extension update added high-risk permissions: ${highRiskAdded.join(', ')}`,
        severity: 'critical',
        weight: 5,
        metadata: {
          extensionId,
          extensionName,
          addedPermissions: highRiskAdded,
          technique: 'permission-escalation'
        }
      }));
    }

    // 2. Detect permission escalation pattern
    if (addedPermissions.length > (rules.escalationThreshold || 3)) {
      findings.push(this.createFinding({
        pattern: 'mass-permission-escalation',
        matched: `${addedPermissions.length} new permissions`,
        description: `Extension added ${addedPermissions.length} permissions in single update`,
        severity: 'high',
        weight: 4,
        metadata: {
          extensionId,
          extensionName,
          addedCount: addedPermissions.length,
          addedPermissions,
          technique: 'bulk-permission-request'
        }
      }));
    }

    // 3. Detect dangerous permission combinations
    const dangerousCombos = this.detectDangerousCombinations(
      newPermissions,
      rules
    );

    if (dangerousCombos.length > 0) {
      for (const combo of dangerousCombos) {
        findings.push(this.createFinding({
          pattern: 'dangerous-permission-combo',
          matched: combo.permissions.join(' + '),
          description: combo.description,
          severity: 'high',
          weight: 4,
          metadata: {
            extensionId,
            extensionName,
            permissions: combo.permissions,
            technique: 'permission-combination-attack'
          }
        }));
      }
    }

    // 4. Detect suspiciously removed permissions (downgrade then re-add pattern)
    if (
      removedPermissions.length > 0 &&
      target.previousUpdate &&
      target.previousUpdate.addedPermissions
    ) {
      const reAddedPermissions = target.previousUpdate.addedPermissions.filter(p =>
        removedPermissions.includes(p)
      );

      if (reAddedPermissions.length > 0) {
        findings.push(this.createFinding({
          pattern: 'permission-churn',
          matched: reAddedPermissions.join(', '),
          description: 'Suspicious permission add/remove pattern detected',
          severity: 'medium',
          weight: 2,
          metadata: {
            extensionId,
            extensionName,
            churnedPermissions: reAddedPermissions,
            technique: 'permission-manipulation'
          }
        }));
      }
    }

    // 5. Detect host permission expansion
    if (this.detectHostExpansion(oldPermissions, newPermissions, rules)) {
      findings.push(this.createFinding({
        pattern: 'host-permission-expansion',
        matched: 'Host permissions expanded',
        description: 'Extension expanded host access permissions',
        severity: 'medium',
        weight: 3,
        metadata: {
          extensionId,
          extensionName,
          technique: 'scope-creep'
        }
      }));
    }

    // 6. Detect silent permission additions (no user prompt)
    if (target.wasAutoUpdate && addedPermissions.length > 0) {
      findings.push(this.createFinding({
        pattern: 'silent-permission-addition',
        matched: `${addedPermissions.length} permissions added silently`,
        description: 'Permissions added during auto-update without user prompt',
        severity: 'high',
        weight: 4,
        metadata: {
          extensionId,
          extensionName,
          addedPermissions,
          technique: 'silent-escalation'
        }
      }));
    }

    const matched = findings.length > 0;
    const riskScore = findings.reduce((sum, f) => sum + (f.weight || 1), 0);

    return this.createResult(matched, findings, riskScore);
  }

  detectDangerousCombinations(permissions, rules) {
    const dangerousCombos = rules.dangerousCombinations || [
      {
        permissions: ['webRequest', 'webRequestBlocking', '<all_urls>'],
        description: 'Can intercept and modify all web traffic'
      },
      {
        permissions: ['clipboardRead', 'clipboardWrite'],
        description: 'Full clipboard access (read and write)'
      },
      {
        permissions: ['cookies', 'webRequest', '<all_urls>'],
        description: 'Can steal cookies from all websites'
      },
      {
        permissions: ['tabs', 'webNavigation', '<all_urls>'],
        description: 'Full browser activity monitoring'
      },
      {
        permissions: ['storage', 'webRequest', '<all_urls>'],
        description: 'Can exfiltrate browsing data'
      }
    ];

    const detected = [];

    for (const combo of dangerousCombos) {
      const hasAll = combo.permissions.every(perm => permissions.includes(perm));
      if (hasAll) {
        detected.push(combo);
      }
    }

    return detected;
  }

  detectHostExpansion(oldPermissions, newPermissions, rules) {
    // Check if <all_urls> was added
    if (!oldPermissions.includes('<all_urls>') && newPermissions.includes('<all_urls>')) {
      return true;
    }

    // Check if wildcard hosts were added
    const oldHosts = oldPermissions.filter(p => p.includes('://'));
    const newHosts = newPermissions.filter(p => p.includes('://'));

    if (newHosts.length > oldHosts.length + 3) {
      return true;
    }

    return false;
  }
}
