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

import { BaseHandler } from './base.js';

/**
 * ARCHITECT mode handler — security architecture & design.
 * Adds: threat-model, controls, design
 */
export class ArchitectHandler extends BaseHandler {
  constructor() { super('architect'); }

  domainActions() {
    return ['threat-model', 'controls', 'design'];
  }

  describeDomain(action) {
    return {
      'threat-model': 'Build STRIDE/DREAD threat model from technique patterns',
      'controls':     'Map security controls (CIS, NIST, ISO) to technique',
      'design':       'Extract architecture design patterns and recommendations',
    }[action];
  }

  async executeDomain(command, ctx) {
    switch (command) {
      case 'threat-model': return this.threatModel(ctx);
      case 'controls':     return this.controls(ctx);
      case 'design':       return this.design(ctx);
      default: throw new Error(`Unknown ARCHITECT command: ${command}`);
    }
  }

  /** Build threat model structure. */
  threatModel(ctx) {
    const { skill, technique } = ctx;
    if (!skill) throw new Error('No SKILL.md found');

    const scope = ctx.flags.scope || 'unspecified';

    // Extract STRIDE elements from content
    const stride = {
      spoofing: [],
      tampering: [],
      repudiation: [],
      informationDisclosure: [],
      dos: [],
      elevationOfPrivilege: [],
    };

    const stridePatterns = {
      spoofing: /spoof|impersonat|forge|fake identity/i,
      tampering: /tamper|modif|alter|inject|manipulat/i,
      repudiation: /repudiat|non-repudiat|audit|log/i,
      informationDisclosure: /disclos|leak|expos|exfiltrat|data breach/i,
      dos: /denial.of.service|dos|ddos|availability|exhaust/i,
      elevationOfPrivilege: /privilege.escalat|elevat|root|admin|bypass auth/i,
    };

    for (const section of skill.sections) {
      for (const [category, pattern] of Object.entries(stridePatterns)) {
        if (pattern.test(section.title) || pattern.test(section.content.slice(0, 200))) {
          stride[category].push({
            source: section.title,
            summary: section.content.slice(0, 200),
          });
        }
      }
    }

    // Extract trust boundaries from diagrams
    const diagrams = skill.codeBlocks
      .filter(b => b.lang === 'mermaid' || /diagram|flow|architect/i.test(b.context))
      .map(b => ({ context: b.context, code: b.code }));

    return {
      action: 'threat-model',
      technique,
      mode: 'ARCHITECT',
      scope,
      attackIds: skill.attackIds,
      stride,
      diagrams: diagrams.slice(0, 5),
      mitigations: this.extractRecommendations(skill),
      status: 'threat_model_complete',
    };
  }

  /** Map security controls. */
  controls(ctx) {
    const { skill, technique } = ctx;
    if (!skill) throw new Error('No SKILL.md found');

    // Extract control references
    const controlRefs = new Set();
    const patterns = [
      /CIS\s*(?:Control\s*)?\d+(?:\.\d+)*/gi,
      /NIST\s*(?:SP\s*)?(?:800-\d+(?:[A-Z])?\s*)?(?:[A-Z]{2}-\d+)?/gi,
      /ISO\s*27\d{3}(?:[-:]\d+(?:\.\d+)*)?/gi,
      /SOC\s*[12](?:\s*Type\s*[12I]+)?/gi,
      /PCI[\s-]DSS\s*(?:v?\d+(?:\.\d+)?\s*)?(?:Req(?:uirement)?\s*\d+(?:\.\d+)*)?/gi,
      /OWASP\s*(?:Top\s*10)?\s*(?:A\d{2}(?::\d{4})?)?/gi,
      /MITRE\s*(?:ATT&CK|D3FEND)/gi,
    ];

    for (const re of patterns) {
      let m;
      while ((m = re.exec(skill.raw))) {
        controlRefs.add(m[0].trim());
      }
    }

    // Extract from tables with control columns
    const controlTables = [];
    for (const table of skill.tables) {
      if (table.headers.some(h => /control|requirement|standard|framework|compliance/i.test(h))) {
        controlTables.push({
          headers: table.headers,
          rows: table.rows.slice(0, 15),
        });
      }
    }

    const controlsList = [...controlRefs];

    return {
      action: 'controls',
      technique,
      mode: 'ARCHITECT',
      attackIds: skill.attackIds,
      controls: controlsList,
      controlValidation: this.validateControlRefs(controlsList),
      controlTables: controlTables.slice(0, 5),
      status: 'controls_complete',
    };
  }

  /** Validate control reference strings against known framework formats. */
  validateControlRefs(controls) {
    if (!Array.isArray(controls)) return { valid: [], invalid: [], total: 0 };
    const patterns = [
      /^CIS\s*(?:Control\s*)?\d+(?:\.\d+)*/i,
      /^NIST\s*(?:SP\s*)?800-\d+/i,
      /^(?:AC|AT|AU|CA|CM|CP|IA|IR|MA|MP|PE|PL|PM|PS|RA|SA|SC|SI|SR)-\d+/i,
      /^ISO\s*27\d{3}/i,
      /^OWASP/i,
      /^PCI[\s-]DSS/i,
      /^SOC\s*[12]/i,
      /^MITRE\s*(?:ATT&CK|D3FEND)/i,
    ];
    const valid = [];
    const invalid = [];
    for (const ref of controls) {
      const s = String(ref).trim();
      if (patterns.some(p => p.test(s))) { valid.push(s); } else { invalid.push(s); }
    }
    return { valid, invalid, total: controls.length };
  }

  /** Extract architecture design patterns. */
  design(ctx) {
    const { skill, technique } = ctx;
    if (!skill) throw new Error('No SKILL.md found');

    // Extract design/architecture sections
    const patterns = skill.sections
      .filter(s => /design|architect|pattern|principle|best.practice|implement/i.test(s.title))
      .map(s => ({
        area: s.title,
        content: s.content.slice(0, 400),
      }));

    // Extract configuration examples
    const configs = skill.codeBlocks
      .filter(b => ['yaml', 'json', 'toml', 'hcl', 'tf', 'xml'].includes(b.lang))
      .map(b => ({
        lang: b.lang,
        context: b.context,
        config: b.code.slice(0, 500),
      }));

    // Extract diagrams
    const diagrams = skill.codeBlocks
      .filter(b => b.lang === 'mermaid')
      .map(b => ({ context: b.context, code: b.code }));

    return {
      action: 'design',
      technique,
      mode: 'ARCHITECT',
      tools: skill.tools,
      patterns: patterns.slice(0, 10),
      configs: configs.slice(0, 10),
      diagrams: diagrams.slice(0, 5),
      recommendations: this.extractRecommendations(skill),
      status: 'design_complete',
    };
  }
}
