// Copyright (c) 2026 defconxt. All rights reserved.
// Licensed under AGPL-3.0 — see LICENSE file for details.
// NERF is a trademark of defconxt.

/**
 * PRIVACY mode agent — Compliance Assessment.
 *
 * Performs execution engine codebase analysis for PII patterns and GDPR triggers.
 * Ported from execution engine/modes/privacy.py.
 *
 * @module execution-engine/modes/privacy
 */

import { ModeAgentConfig, ToolRegistry } from '../framework.js';
import { DPIAValidator } from '../validators/privacy.js';

// ---------------------------------------------------------------------------
// PII regex patterns (inline — NOT imported from skills/)
// ---------------------------------------------------------------------------

/** @type {Object<string, [RegExp, string]>} */
export const PII_PATTERNS = {
  ssn: [
    /\b\d{3}-\d{2}-\d{4}\b/g,
    'Social Security Number',
  ],
  credit_card: [
    /\b(?:4\d{3}|5[1-5]\d{2}|3[47]\d{2}|6(?:011|5\d{2}))[- ]?\d{4}[- ]?\d{4}[- ]?\d{4}\b/g,
    'Credit Card Number',
  ],
  email: [
    /\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}\b/g,
    'Email Address',
  ],
  phone: [
    /\b(?:\+1[- ]?)?\(?\d{3}\)?[- ]?\d{3}[- ]?\d{4}\b/g,
    'US Phone Number',
  ],
  ip_address: [
    /\b(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\b/g,
    'IP Address',
  ],
};

// ---------------------------------------------------------------------------
// WP29 DPIA criteria and trigger keywords
// ---------------------------------------------------------------------------

export const WP29_CRITERIA = [
  'Evaluation or scoring (profiling, predicting)',
  'Automated decision-making with legal/significant effect',
  'Systematic monitoring (observation, tracking)',
  'Sensitive data or data of highly personal nature',
  'Data processed on a large scale',
  'Matching or combining datasets',
  'Data concerning vulnerable subjects',
  'Innovative use of new technology',
  'Cross-border transfer outside EEA',
  'Processing prevents exercising data subject rights',
];

export const TRIGGER_KEYWORDS = {
  'profiling': 0,
  'scoring': 0,
  'automated decision': 1,
  'systematic monitoring': 2,
  'surveillance': 2,
  'health': 3,
  'biometric': 3,
  'genetic': 3,
  'racial': 3,
  'political': 3,
  'large-scale': 4,
  'large scale': 4,
  'combining': 5,
  'matching': 5,
  'children': 6,
  'employee': 6,
  'patient': 6,
  'vulnerable': 6,
  'innovative': 7,
  'new technology': 7,
  'cross-border': 8,
  'transfer': 8,
  'prevent': 9,
  'restrict': 9,
};

// ---------------------------------------------------------------------------
// Tool handlers
// ---------------------------------------------------------------------------

/**
 * Scan source code content for PII patterns using inline regexes.
 * @param {*} context
 * @param {Object} toolInput
 * @returns {string}
 */
export function _privacyScanCodebase(context, toolInput) {
  const codeContent = toolInput.code_content || '';
  if (!codeContent) {
    return "ERROR: 'code_content' parameter is required.";
  }

  const filename = toolInput.filename || '<unknown>';
  const findings = [];

  const lines = codeContent.split('\n');
  for (const [piiType, [pattern, label]] of Object.entries(PII_PATTERNS)) {
    for (let lineNum = 0; lineNum < lines.length; lineNum++) {
      const line = lines[lineNum];
      // Reset regex lastIndex for each line (global flag)
      pattern.lastIndex = 0;
      let match;
      while ((match = pattern.exec(line)) !== null) {
        findings.push({
          type: piiType,
          label,
          line: lineNum + 1,
          match: match[0],
        });
      }
    }
  }

  return JSON.stringify({
    filename,
    findings,
    total_findings: findings.length,
  }, null, 2);
}

/**
 * Evaluate WP29 DPIA trigger criteria against a processing description.
 * @param {*} context
 * @param {Object} toolInput
 * @returns {string}
 */
export function _privacyAssessDpiaTriggers(context, toolInput) {
  const description = toolInput.processing_description || '';
  if (!description) {
    return "ERROR: 'processing_description' parameter is required.";
  }

  const descLower = description.toLowerCase();
  const matchedIndices = new Set();

  for (const [keyword, index] of Object.entries(TRIGGER_KEYWORDS)) {
    if (descLower.includes(keyword)) {
      matchedIndices.add(index);
    }
  }

  const matchedCriteria = [...matchedIndices].sort((a, b) => a - b).map(i => WP29_CRITERIA[i]);
  const dpiaRequired = matchedIndices.size >= 2;

  return JSON.stringify({
    processing_description: description,
    criteria_matched: matchedCriteria,
    criteria_count: matchedCriteria.length,
    dpia_required: dpiaRequired,
    reasoning: dpiaRequired
      ? `DPIA required: ${matchedCriteria.length} WP29 criteria matched (threshold: 2)`
      : `DPIA may not be required: only ${matchedCriteria.length} criteria matched`,
    article_35_3_triggers: {
      systematic_profiling: [0, 1].some(i => matchedIndices.has(i)),
      special_category_large_scale: [3, 4].every(i => matchedIndices.has(i)),
      systematic_public_monitoring: matchedIndices.has(2) && matchedIndices.has(4),
    },
  }, null, 2);
}

/**
 * Store a structured JSON DPIA report in context.
 * @param {*} context
 * @param {Object} toolInput
 * @returns {string}
 */
export function _privacyWriteDpiaReport(context, toolInput) {
  const report = toolInput.report || '';

  if (typeof context !== 'object' || context === null) {
    return 'ERROR: Context must be a dict.';
  }

  let reportData;
  if (typeof report === 'string') {
    try {
      reportData = JSON.parse(report);
    } catch {
      reportData = report;
    }
  } else {
    reportData = report;
  }

  context.report = reportData;
  const filename = toolInput.filename || 'dpia_report.json';

  return (
    `DPIA report stored as ${filename}. ` +
    `Report is available in context['report'].`
  );
}

// ---------------------------------------------------------------------------
// Tool schemas (Anthropic format)
// ---------------------------------------------------------------------------

const _PRIVACY_SCAN_CODEBASE_SCHEMA = {
  name: 'scan_codebase',
  description:
    'Scan source code content for PII patterns (SSN, credit card, email, phone, ' +
    'IP address) using regex matching. Returns findings with type, label, line, match.',
  input_schema: {
    type: 'object',
    properties: {
      code_content: {
        type: 'string',
        description: 'Source code content to scan for PII patterns',
      },
      filename: {
        type: 'string',
        description: 'Optional filename for attribution in results',
      },
    },
    required: ['code_content'],
  },
};

const _PRIVACY_ASSESS_DPIA_TRIGGERS_SCHEMA = {
  name: 'assess_dpia_triggers',
  description:
    'Evaluate a data processing description against WP29 DPIA trigger criteria. ' +
    'Returns matched criteria, count, DPIA determination, and Article 35(3) triggers.',
  input_schema: {
    type: 'object',
    properties: {
      processing_description: {
        type: 'string',
        description: 'Description of the data processing activity to assess',
      },
    },
    required: ['processing_description'],
  },
};

const _PRIVACY_WRITE_DPIA_REPORT_SCHEMA = {
  name: 'write_dpia_report',
  description:
    'Submit the completed DPIA report as JSON with required sections: ' +
    'processing_description, data_flows, legal_basis, risk_assessment, ' +
    'mitigations, gdpr_articles, findings.',
  input_schema: {
    type: 'object',
    properties: {
      report: {
        type: 'string',
        description:
          'Full JSON DPIA report with processing_description, data_flows, ' +
          'legal_basis, risk_assessment, mitigations, gdpr_articles, findings.',
      },
      filename: {
        type: 'string',
        description: 'Filename for the report (e.g. dpia_report.json)',
      },
    },
    required: ['report'],
  },
};

// ---------------------------------------------------------------------------
// System prompt template
// ---------------------------------------------------------------------------

const _PRIVACY_SYSTEM_PROMPT = `\
You are an expert privacy engineer and GDPR compliance analyst. Your task is \
to analyze a codebase for data processing activities and produce a structured \
Data Protection Impact Assessment (DPIA) report.

## Codebase
Description: {codebase_description}
Files: {file_listing}

## Instructions
1. Use \`scan_codebase\` to scan each source file for PII patterns.
2. Use \`assess_dpia_triggers\` to evaluate WP29 criteria.
3. Produce a structured JSON DPIA report using \`write_dpia_report\`.

## Rules
- Cite specific GDPR articles (e.g., Art. 35)
- Assess all WP29 DPIA trigger criteria systematically
- Flag any PII found in source code as high-priority findings
- Document data flows completely
`;

// ---------------------------------------------------------------------------
// Output parser (fallback for text-based output)
// ---------------------------------------------------------------------------

/**
 * Extract JSON DPIA report from LLM text output.
 * @param {string} text
 * @returns {Object}
 */
export function _privacyOutputParser(text) {
  if (!text || !text.trim()) {
    return { raw_text: text, parse_error: 'empty output' };
  }

  let matches = [...text.matchAll(/```json\s*\n(.*?)```/gs)].map(m => m[1]);
  if (matches.length > 0) {
    const jsonText = matches.join('\n');
    try { return JSON.parse(jsonText); } catch (e) {
      return { raw_text: text, parse_error: e.message };
    }
  }

  matches = [...text.matchAll(/```\s*\n(.*?)```/gs)].map(m => m[1]);
  if (matches.length > 0) {
    const jsonText = matches.join('\n');
    try { return JSON.parse(jsonText); } catch (e) {
      return { raw_text: text, parse_error: e.message };
    }
  }

  try { return JSON.parse(text); } catch (e) {
    return { raw_text: text, parse_error: e.message };
  }
}

// ---------------------------------------------------------------------------
// Factory function
// ---------------------------------------------------------------------------

/**
 * Build a PRIVACY-mode ModeAgentConfig for compliance assessment.
 * @returns {ModeAgentConfig}
 */
function _makePrivacyConfig() {
  const reg = new ToolRegistry();
  reg.register('scan_codebase', _PRIVACY_SCAN_CODEBASE_SCHEMA, _privacyScanCodebase);
  reg.register('assess_dpia_triggers', _PRIVACY_ASSESS_DPIA_TRIGGERS_SCHEMA, _privacyAssessDpiaTriggers);
  reg.register('write_dpia_report', _PRIVACY_WRITE_DPIA_REPORT_SCHEMA, _privacyWriteDpiaReport);

  return new ModeAgentConfig({
    mode: 'PRIVACY',
    toolRegistry: reg,
    systemPromptTemplate: _PRIVACY_SYSTEM_PROMPT,
    validator: new DPIAValidator(),
    maxTurns: 15,
    requiresSandbox: false,
    completionCheck: null,
    outputParser: _privacyOutputParser,
    outputFormat: 'json',
  });
}

// ---------------------------------------------------------------------------
// Registration function — called by runner.initModes()
// ---------------------------------------------------------------------------

/**
 * Register PRIVACY mode with the given registerMode function.
 * @param {Function} registerMode
 */
export function register(registerMode) {
  registerMode('PRIVACY', _makePrivacyConfig);
}
