// Base Detector - Abstract base class for all detector modules
// Provides common interface and utilities

export class BaseDetector {
  constructor(config = {}) {
    this.name = config.name || 'base-detector';
    this.category = config.category || 'general';
    this.version = config.version || '1.0.0';
    this.description = config.description || '';
    this.enabled = config.enabled !== false;
    this.weight = config.weight || 1;
    this.severity = config.severity || 'medium';
  }

  /**
   * Main detection method - must be implemented by subclasses
   * @param {object} target - Analysis target { url, type, resource, etc. }
   * @param {object} ruleRegistry - Rule registry instance
   * @returns {object} - { detector, matched, findings[], riskScore }
   */
  async detect(target, ruleRegistry) {
    throw new Error('detect() must be implemented by subclass');
  }

  /**
   * Create finding object
   * @param {object} data - Finding data
   * @returns {object} - Standardized finding
   */
  createFinding(data) {
    return {
      detector: this.name,
      category: this.category,
      severity: data.severity || this.severity,
      weight: data.weight || this.weight,
      pattern: data.pattern || null,
      matched: data.matched || null,
      description: data.description || '',
      metadata: data.metadata || {},
      timestamp: Date.now()
    };
  }

  /**
   * Create detection result
   * @param {boolean} matched - Whether detection matched
   * @param {array} findings - Array of findings
   * @param {number} riskScore - Calculated risk score
   * @returns {object} - Detection result
   */
  createResult(matched, findings = [], riskScore = 0) {
    return {
      detector: this.name,
      matched,
      findings,
      riskScore: riskScore || (matched ? findings.length * this.weight : 0),
      timestamp: Date.now()
    };
  }

  /**
   * Test regex pattern against value
   * @param {RegExp} pattern - Regex pattern
   * @param {string} value - Value to test
   * @returns {boolean} - True if matched
   */
  testPattern(pattern, value) {
    if (!pattern || !value) return false;
    try {
      return pattern.test(value);
    } catch (error) {
      console.error(`[${this.name}] Pattern test error:`, error);
      return false;
    }
  }

  /**
   * Extract domain from URL
   * @param {string} url - URL string
   * @returns {string} - Domain or null
   */
  extractDomain(url) {
    try {
      const urlObj = new URL(url);
      return urlObj.hostname;
    } catch (error) {
      return null;
    }
  }

  /**
   * Extract path from URL
   * @param {string} url - URL string
   * @returns {string} - Path or null
   */
  extractPath(url) {
    try {
      const urlObj = new URL(url);
      return urlObj.pathname;
    } catch (error) {
      return null;
    }
  }

  /**
   * Extract query parameters from URL
   * @param {string} url - URL string
   * @returns {object} - Query params object
   */
  extractQueryParams(url) {
    try {
      const urlObj = new URL(url);
      const params = {};
      for (const [key, value] of urlObj.searchParams) {
        params[key] = value;
      }
      return params;
    } catch (error) {
      return {};
    }
  }

  /**
   * Enable/disable detector
   * @param {boolean} enabled - Enable state
   */
  setEnabled(enabled) {
    this.enabled = enabled;
  }

  /**
   * Get detector info
   * @returns {object} - Detector information
   */
  getInfo() {
    return {
      name: this.name,
      category: this.category,
      version: this.version,
      description: this.description,
      enabled: this.enabled,
      weight: this.weight,
      severity: this.severity
    };
  }
}
