import { ConfigManager } from '../../config/config-manager.js';
import { 
  SecurityConfig, 
  SecurityScanResult, 
  SecurityFinding, 
  SecretPattern, 
  SecretFinding,
  VulnerabilityReport,
  SecuritySetupConfig,
  SecuritySetupResult,
  SecurityReport
} from './types.js';
import { promises as fs } from 'fs';
import path from 'path';
import { exec } from 'child_process';
import { promisify } from 'util';

const execAsync = promisify(exec);

export class SecurityScanner {
  private configManager: ConfigManager;
  private secretPatterns: SecretPattern[];

  constructor(configManager: ConfigManager) {
    this.configManager = configManager;
    this.secretPatterns = this.initializeSecretPatterns();
  }

  async performScan(config: SecurityConfig): Promise<SecurityScanResult> {
    const startTime = Date.now();
    const findings: SecurityFinding[] = [];

    try {
      // Scan for secrets
      if (config.includeSecrets) {
        const secretFindings = await this.scanForSecrets({ scanPath: '.' });
        findings.push(...this.convertSecretsToFindings(secretFindings));
      }

      // Check dependencies
      if (config.includeDependencies) {
        const vulnReport = await this.checkVulnerabilities({ checkNpm: true });
        findings.push(...this.convertVulnerabilitiesToFindings(vulnReport));
      }

      // Scan files for security issues
      if (config.includeFiles) {
        const fileFindings = await this.scanSourceFiles();
        findings.push(...fileFindings);
      }

      // Check permissions
      if (config.includePermissions) {
        const permissionFindings = await this.checkPermissions();
        findings.push(...permissionFindings);
      }

      const endTime = Date.now();
      const summary = this.calculateSummary(findings, endTime - startTime);

      return {
        summary,
        findings,
        recommendations: this.generateRecommendations(findings),
        metadata: {
          scanDate: new Date().toISOString(),
          scanType: config.scanType,
          version: '1.0.0',
        },
      };
    } catch (error) {
      throw new Error(`Security scan failed: ${(error as Error).message}`);
    }
  }

  async scanForSecrets(options: {
    scanPath: string;
    excludePaths?: string[];
    customPatterns?: string[];
  }): Promise<SecretFinding[]> {
    const secrets: SecretFinding[] = [];
    const excludePaths = options.excludePaths || ['.git', 'node_modules', '.atlas'];

    await this.scanDirectory(options.scanPath, secrets, excludePaths);
    return secrets;
  }

  async checkVulnerabilities(options: {
    checkNpm?: boolean;
    checkYarn?: boolean;
    severity?: string;
    autoFix?: boolean;
  }): Promise<VulnerabilityReport> {
    const report: VulnerabilityReport = {
      total: 0,
      critical: 0,
      high: 0,
      moderate: 0,
      low: 0,
      details: [],
      lastChecked: new Date().toISOString(),
    };

    try {
      if (options.checkNpm) {
        // Check if package.json exists
        const packageJsonPath = path.join(process.cwd(), 'package.json');
        try {
          await fs.access(packageJsonPath);
          const npmAuditResult = await this.runNpmAudit(options.autoFix);
          this.mergeVulnerabilityReport(report, npmAuditResult);
        } catch {
          // No package.json, skip npm check
        }
      }
    } catch (error) {
      // Handle audit errors gracefully
    }

    return report;
  }

  async setupSecurityConfiguration(config: SecuritySetupConfig): Promise<SecuritySetupResult> {
    const filesCreated: string[] = [];
    const toolsConfigured: string[] = [];
    const nextSteps: string[] = [];

    if (config.createSecurityPolicy) {
      await this.createSecurityPolicy();
      filesCreated.push('SECURITY.md');
      toolsConfigured.push('Security Policy');
    }

    if (config.enableSecretDetection) {
      await this.setupSecretDetection();
      filesCreated.push('.gitleaks.toml');
      toolsConfigured.push('Secret Detection');
      nextSteps.push('Install gitleaks: brew install gitleaks (macOS) or download from GitHub');
    }

    if (config.enableVulnerabilityChecks) {
      await this.setupVulnerabilityChecks();
      filesCreated.push('.github/workflows/security.yml');
      toolsConfigured.push('Vulnerability Scanning');
    }

    if (config.setupGitHooks && config.enablePreCommitScans) {
      await this.setupSecurityGitHooks();
      filesCreated.push('.git/hooks/pre-commit');
      toolsConfigured.push('Git Hooks');
      nextSteps.push('Make Git hooks executable: chmod +x .git/hooks/pre-commit');
    }

    if (config.enablePreCommitScans) {
      await this.setupPreCommitConfig();
      filesCreated.push('.pre-commit-config.yaml');
      toolsConfigured.push('Pre-commit Security');
      nextSteps.push('Install pre-commit: pip install pre-commit && pre-commit install');
    }

    return { filesCreated, toolsConfigured, nextSteps };
  }

  async generateSecurityReport(options: {
    includeOverview: boolean;
    includeDetails: boolean;
    includeRecommendations: boolean;
  }): Promise<SecurityReport> {
    // Perform a comprehensive scan
    const scanResult = await this.performScan({
      scanType: 'comprehensive',
      includeFiles: true,
      includeDependencies: true,
      includeSecrets: true,
      includePermissions: true,
      outputFormat: 'detailed',
    });

    const sections: any = {};
    let markdown = '# Security Report\n\n';

    if (options.includeOverview) {
      sections.overview = this.generateOverviewSection(scanResult);
      markdown += sections.overview + '\n\n';
    }

    if (options.includeDetails) {
      sections.details = this.generateDetailsSection(scanResult);
      markdown += sections.details + '\n\n';
    }

    if (options.includeRecommendations) {
      sections.recommendations = this.generateRecommendationsSection(scanResult);
      markdown += sections.recommendations + '\n\n';
    }

    return {
      markdown,
      summary: scanResult.summary,
      sections,
    };
  }

  private initializeSecretPatterns(): SecretPattern[] {
    return [
      {
        name: 'AWS Access Key',
        pattern: /AKIA[0-9A-Z]{16}/gi,
        severity: 'high',
        description: 'AWS Access Key ID detected',
      },
      {
        name: 'AWS Secret Key',
        pattern: /[0-9a-zA-Z/+]{40}/gi,
        severity: 'high',
        description: 'Potential AWS Secret Access Key',
      },
      {
        name: 'GitHub Token',
        pattern: /ghp_[0-9a-zA-Z]{36}/gi,
        severity: 'high',
        description: 'GitHub Personal Access Token',
      },
      {
        name: 'API Key',
        pattern: /api[_-]?key[_-]?[=:]\s*['\"]?[0-9a-zA-Z]{20,}['\"]?/gi,
        severity: 'medium',
        description: 'Generic API key pattern',
      },
      {
        name: 'Database URL',
        pattern: /(mongodb|mysql|postgres):\/\/[^\s]+/gi,
        severity: 'medium',
        description: 'Database connection string',
      },
      {
        name: 'Private Key',
        pattern: /-----BEGIN (RSA )?PRIVATE KEY-----/gi,
        severity: 'high',
        description: 'Private key detected',
      },
      {
        name: 'JWT Token',
        pattern: /eyJ[0-9a-zA-Z+/]+=*\./gi,
        severity: 'medium',
        description: 'JSON Web Token detected',
      },
    ];
  }

  private async scanDirectory(dirPath: string, secrets: SecretFinding[], excludePaths: string[]): Promise<void> {
    try {
      const items = await fs.readdir(dirPath, { withFileTypes: true });

      for (const item of items) {
        const fullPath = path.join(dirPath, item.name);
        const relativePath = path.relative(process.cwd(), fullPath);

        // Skip excluded paths
        if (excludePaths.some(exclude => relativePath.includes(exclude))) {
          continue;
        }

        if (item.isDirectory()) {
          await this.scanDirectory(fullPath, secrets, excludePaths);
        } else if (item.isFile() && this.shouldScanFile(item.name)) {
          await this.scanFile(fullPath, secrets);
        }
      }
    } catch (error) {
      // Skip directories we can't read
    }
  }

  private shouldScanFile(filename: string): boolean {
    const textExtensions = ['.js', '.ts', '.jsx', '.tsx', '.json', '.md', '.txt', '.env', '.yml', '.yaml', '.toml', '.ini'];
    const ext = path.extname(filename).toLowerCase();
    return textExtensions.includes(ext) || filename.startsWith('.env');
  }

  private async scanFile(filePath: string, secrets: SecretFinding[]): Promise<void> {
    try {
      const content = await fs.readFile(filePath, 'utf-8');
      const lines = content.split('\n');

      lines.forEach((line, lineNumber) => {
        for (const pattern of this.secretPatterns) {
          const matches = line.match(pattern.pattern);
          if (matches) {
            matches.forEach(match => {
              secrets.push({
                type: pattern.name,
                file: path.relative(process.cwd(), filePath),
                line: lineNumber + 1,
                pattern: match.substring(0, 50) + (match.length > 50 ? '...' : ''),
                severity: pattern.severity,
                context: line.trim(),
              });
            });
          }
        }
      });
    } catch (error) {
      // Skip files we can't read
    }
  }

  private async scanSourceFiles(): Promise<SecurityFinding[]> {
    const findings: SecurityFinding[] = [];

    // Check for common security anti-patterns in code
    const patterns = [
      {
        pattern: /eval\s*\(/gi,
        title: 'Dangerous eval() usage',
        severity: 'high' as const,
        description: 'Use of eval() can lead to code injection vulnerabilities',
        recommendation: 'Avoid using eval(). Use JSON.parse() for JSON or other safe alternatives',
      },
      {
        pattern: /innerHTML\s*=/gi,
        title: 'Potential XSS via innerHTML',
        severity: 'medium' as const,
        description: 'Direct innerHTML assignment can lead to XSS vulnerabilities',
        recommendation: 'Use textContent, createTextNode, or sanitize input before using innerHTML',
      },
      {
        pattern: /document\.write\s*\(/gi,
        title: 'Dangerous document.write usage',
        severity: 'medium' as const,
        description: 'document.write can be vulnerable to XSS attacks',
        recommendation: 'Use modern DOM manipulation methods instead of document.write',
      },
    ];

    try {
      await this.scanForCodePatterns(patterns, findings);
    } catch (error) {
      // Handle scan errors gracefully
    }

    return findings;
  }

  private async scanForCodePatterns(
    patterns: Array<{
      pattern: RegExp;
      title: string;
      severity: 'critical' | 'high' | 'medium' | 'low';
      description: string;
      recommendation: string;
    }>,
    findings: SecurityFinding[]
  ): Promise<void> {
    const scanPath = process.cwd();
    await this.scanDirectoryForPatterns(scanPath, patterns, findings);
  }

  private async scanDirectoryForPatterns(
    dirPath: string,
    patterns: any[],
    findings: SecurityFinding[]
  ): Promise<void> {
    try {
      const items = await fs.readdir(dirPath, { withFileTypes: true });

      for (const item of items) {
        const fullPath = path.join(dirPath, item.name);
        const relativePath = path.relative(process.cwd(), fullPath);

        // Skip excluded paths
        if (['node_modules', '.git', '.atlas', 'dist', 'build'].some(exclude => relativePath.includes(exclude))) {
          continue;
        }

        if (item.isDirectory()) {
          await this.scanDirectoryForPatterns(fullPath, patterns, findings);
        } else if (item.isFile() && this.shouldScanForCode(item.name)) {
          await this.scanFileForPatterns(fullPath, patterns, findings);
        }
      }
    } catch (error) {
      // Skip directories we can't read
    }
  }

  private shouldScanForCode(filename: string): boolean {
    const codeExtensions = ['.js', '.ts', '.jsx', '.tsx', '.html', '.php', '.py'];
    const ext = path.extname(filename).toLowerCase();
    return codeExtensions.includes(ext);
  }

  private async scanFileForPatterns(
    filePath: string,
    patterns: any[],
    findings: SecurityFinding[]
  ): Promise<void> {
    try {
      const content = await fs.readFile(filePath, 'utf-8');
      const lines = content.split('\n');

      lines.forEach((line, lineNumber) => {
        for (const pattern of patterns) {
          if (pattern.pattern.test(line)) {
            findings.push({
              id: `code-${findings.length + 1}`,
              title: pattern.title,
              description: pattern.description,
              severity: pattern.severity,
              category: 'code',
              file: path.relative(process.cwd(), filePath),
              line: lineNumber + 1,
              recommendation: pattern.recommendation,
            });
          }
        }
      });
    } catch (error) {
      // Skip files we can't read
    }
  }

  private async checkPermissions(): Promise<SecurityFinding[]> {
    const findings: SecurityFinding[] = [];

    try {
      // Check for overly permissive files
      const sensitiveFiles = ['.env', '.env.local', 'id_rsa', 'id_ed25519', '.ssh/id_rsa'];
      
      for (const file of sensitiveFiles) {
        try {
          const stats = await fs.stat(path.join(process.cwd(), file));
          const mode = stats.mode & parseInt('777', 8);
          
          if (mode & parseInt('044', 8)) { // Readable by group or others
            findings.push({
              id: `perm-${findings.length + 1}`,
              title: 'Overly permissive file permissions',
              description: `File ${file} is readable by group or others`,
              severity: 'medium',
              category: 'permissions',
              file,
              recommendation: `Run: chmod 600 ${file}`,
            });
          }
        } catch {
          // File doesn't exist, skip
        }
      }
    } catch (error) {
      // Handle permission check errors
    }

    return findings;
  }

  private async runNpmAudit(autoFix: boolean = false): Promise<VulnerabilityReport> {
    try {
      const command = autoFix ? 'npm audit fix --json' : 'npm audit --json';
      const { stdout } = await execAsync(command);
      
      const auditResult = JSON.parse(stdout);
      
      return {
        total: auditResult.metadata?.vulnerabilities?.total || 0,
        critical: auditResult.metadata?.vulnerabilities?.critical || 0,
        high: auditResult.metadata?.vulnerabilities?.high || 0,
        moderate: auditResult.metadata?.vulnerabilities?.moderate || 0,
        low: auditResult.metadata?.vulnerabilities?.low || 0,
        lastChecked: new Date().toISOString(),
        details: this.parseNpmAuditDetails(auditResult),
      };
    } catch (error) {
      // npm audit returns non-zero exit code when vulnerabilities found
      // Try to parse the error output
      try {
        const errorOutput = (error as any).stdout || '{}';
        const auditResult = JSON.parse(errorOutput);
        
        return {
          total: auditResult.metadata?.vulnerabilities?.total || 0,
          critical: auditResult.metadata?.vulnerabilities?.critical || 0,
          high: auditResult.metadata?.vulnerabilities?.high || 0,
          moderate: auditResult.metadata?.vulnerabilities?.moderate || 0,
          low: auditResult.metadata?.vulnerabilities?.low || 0,
          lastChecked: new Date().toISOString(),
          details: this.parseNpmAuditDetails(auditResult),
        };
      } catch {
        return {
          total: 0,
          critical: 0,
          high: 0,
          moderate: 0,
          low: 0,
          lastChecked: new Date().toISOString(),
        };
      }
    }
  }

  private parseNpmAuditDetails(auditResult: any): any[] {
    const details: any[] = [];
    
    if (auditResult.vulnerabilities) {
      Object.entries(auditResult.vulnerabilities).forEach(([name, vuln]: [string, any]) => {
        details.push({
          name: vuln.title || name,
          package: name,
          severity: vuln.severity,
          description: vuln.overview || 'No description available',
          recommendation: vuln.recommendation || 'Update to latest version',
          cve: vuln.cves?.[0],
        });
      });
    }
    
    return details.slice(0, 10); // Limit to top 10
  }

  private mergeVulnerabilityReport(target: VulnerabilityReport, source: VulnerabilityReport): void {
    target.total += source.total;
    target.critical += source.critical;
    target.high += source.high;
    target.moderate += source.moderate;
    target.low += source.low;
    
    if (source.details) {
      target.details = [...(target.details || []), ...source.details];
    }
  }

  private convertSecretsToFindings(secrets: SecretFinding[]): SecurityFinding[] {
    return secrets.map((secret, index) => ({
      id: `secret-${index + 1}`,
      title: `Exposed ${secret.type}`,
      description: `Potential ${secret.type} found in source code`,
      severity: secret.severity as 'critical' | 'high' | 'medium' | 'low',
      category: 'secrets' as const,
      file: secret.file,
      line: secret.line,
      recommendation: 'Remove the secret and use environment variables or secure secret management',
    }));
  }

  private convertVulnerabilitiesToFindings(vulnReport: VulnerabilityReport): SecurityFinding[] {
    const findings: SecurityFinding[] = [];
    
    if (vulnReport.details) {
      vulnReport.details.forEach((vuln, index) => {
        findings.push({
          id: `vuln-${index + 1}`,
          title: `Vulnerable dependency: ${vuln.name}`,
          description: vuln.description,
          severity: this.mapVulnerabilitySeverity(vuln.severity),
          category: 'dependencies',
          recommendation: vuln.recommendation,
          cwe: vuln.cve,
        });
      });
    }
    
    return findings;
  }

  private mapVulnerabilitySeverity(severity: string): 'critical' | 'high' | 'medium' | 'low' {
    switch (severity.toLowerCase()) {
      case 'critical': return 'critical';
      case 'high': return 'high';
      case 'moderate': return 'medium';
      case 'low': return 'low';
      default: return 'medium';
    }
  }

  private calculateSummary(findings: SecurityFinding[], scanTime: number) {
    const critical = findings.filter(f => f.severity === 'critical').length;
    const high = findings.filter(f => f.severity === 'high').length;
    const medium = findings.filter(f => f.severity === 'medium').length;
    const low = findings.filter(f => f.severity === 'low').length;
    
    const status: 'pass' | 'warning' | 'fail' = critical > 0 ? 'fail' : high > 0 ? 'warning' : 'pass';
    
    return {
      status,
      totalIssues: findings.length,
      critical,
      high,
      medium,
      low,
      scanTime,
    };
  }

  private generateRecommendations(findings: SecurityFinding[]): string[] {
    const recommendations = new Set<string>();
    
    if (findings.some(f => f.category === 'secrets')) {
      recommendations.add('Implement proper secret management using environment variables');
      recommendations.add('Add secret scanning to your CI/CD pipeline');
    }
    
    if (findings.some(f => f.category === 'dependencies')) {
      recommendations.add('Regularly update dependencies to patch vulnerabilities');
      recommendations.add('Enable automated dependency scanning');
    }
    
    if (findings.some(f => f.category === 'code')) {
      recommendations.add('Review and fix code security issues');
      recommendations.add('Implement secure coding practices');
    }
    
    recommendations.add('Set up automated security scanning in pre-commit hooks');
    recommendations.add('Create a security policy and incident response plan');
    
    return Array.from(recommendations);
  }

  private generateOverviewSection(scanResult: SecurityScanResult): string {
    return `## Security Overview

**Scan Date**: ${scanResult.metadata.scanDate}
**Scan Type**: ${scanResult.metadata.scanType}
**Overall Status**: ${scanResult.summary.status === 'pass' ? '✅ PASS' : scanResult.summary.status === 'warning' ? '⚠️ WARNING' : '❌ FAIL'}

### Summary
- **Total Issues**: ${scanResult.summary.totalIssues}
- **Critical**: ${scanResult.summary.critical}
- **High**: ${scanResult.summary.high}
- **Medium**: ${scanResult.summary.medium}
- **Low**: ${scanResult.summary.low}

### Risk Assessment
${scanResult.summary.critical > 0 ? '🔴 **HIGH RISK**: Critical vulnerabilities require immediate attention' : 
  scanResult.summary.high > 0 ? '🟠 **MEDIUM RISK**: High severity issues should be addressed promptly' :
  scanResult.summary.medium > 0 ? '🟡 **LOW RISK**: Medium severity issues should be planned for resolution' :
  '🟢 **MINIMAL RISK**: No critical security issues detected'}`;
  }

  private generateDetailsSection(scanResult: SecurityScanResult): string {
    if (scanResult.findings.length === 0) {
      return '## Detailed Findings\n\n✅ No security issues found in this scan.';
    }

    const sections = [];
    sections.push('## Detailed Findings\n');

    const categorized = this.categorizeFindings(scanResult.findings);
    
    Object.entries(categorized).forEach(([category, findings]) => {
      if (findings.length > 0) {
        sections.push(`### ${this.getCategoryTitle(category)}\n`);
        findings.forEach((finding, i) => {
          const emoji = this.getSeverityEmoji(finding.severity);
          sections.push(`${i + 1}. ${emoji} **${finding.title}** (${finding.severity})`);
          sections.push(`   - **Description**: ${finding.description}`);
          if (finding.file) sections.push(`   - **File**: ${finding.file}${finding.line ? `:${finding.line}` : ''}`);
          if (finding.recommendation) sections.push(`   - **Recommendation**: ${finding.recommendation}`);
          sections.push('');
        });
      }
    });

    return sections.join('\n');
  }

  private generateRecommendationsSection(scanResult: SecurityScanResult): string {
    const recommendations = scanResult.recommendations || [];
    
    if (recommendations.length === 0) {
      return '## Recommendations\n\n✅ No specific recommendations at this time. Continue following security best practices.';
    }

    return `## Recommendations

${recommendations.map((rec, i) => `${i + 1}. ${rec}`).join('\n')}

### Additional Resources
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
- [NIST Cybersecurity Framework](https://www.nist.gov/cyberframework)
- [Security Code Review Guidelines](https://owasp.org/www-project-code-review-guide/)`;
  }

  private categorizeFindings(findings: SecurityFinding[]): Record<string, SecurityFinding[]> {
    return findings.reduce((acc, finding) => {
      if (!acc[finding.category]) acc[finding.category] = [];
      acc[finding.category].push(finding);
      return acc;
    }, {} as Record<string, SecurityFinding[]>);
  }

  private getCategoryTitle(category: string): string {
    const titles: Record<string, string> = {
      secrets: '🔐 Secrets and Credentials',
      dependencies: '📦 Dependency Vulnerabilities',
      code: '💻 Code Security Issues',
      permissions: '🔒 File Permissions',
      configuration: '⚙️ Configuration Issues',
    };
    return titles[category] || category;
  }

  private getSeverityEmoji(severity: string): string {
    switch (severity) {
      case 'critical': return '🔴';
      case 'high': return '🟠';
      case 'medium': return '🟡';
      case 'low': return '🔵';
      default: return '⚪';
    }
  }

  private async createSecurityPolicy(): Promise<void> {
    const policy = `# Security Policy

## Supported Versions

We release patches for security vulnerabilities. Which versions are eligible for receiving such patches depends on the CVSS v3.0 Rating:

| Version | Supported          |
| ------- | ------------------ |
| 1.x.x   | :white_check_mark: |

## Reporting a Vulnerability

If you discover a security vulnerability, please follow these steps:

1. **Do not** open a public issue
2. Send an email to [security@yourproject.com] with:
   - Description of the vulnerability
   - Steps to reproduce
   - Potential impact
   - Any suggested fixes

## Security Measures

This project implements the following security measures:

- Automated dependency scanning
- Secret detection in CI/CD
- Code security analysis
- Regular security audits

## Response Timeline

- Initial response: Within 48 hours
- Status update: Within 1 week
- Resolution: Varies based on severity

## Security Best Practices

- Keep dependencies up to date
- Use environment variables for secrets
- Follow secure coding practices
- Enable two-factor authentication
- Regularly review access permissions
`;

    await fs.writeFile(path.join(process.cwd(), 'SECURITY.md'), policy);
  }

  private async setupSecretDetection(): Promise<void> {
    const gitleaksConfig = `# Gitleaks configuration
title = "Gitleaks Config"

[[rules]]
id = "aws-access-key"
description = "AWS Access Key"
regex = '''AKIA[0-9A-Z]{16}'''

[[rules]]
id = "github-token"
description = "GitHub Token"
regex = '''ghp_[0-9a-zA-Z]{36}'''

[[rules]]
id = "api-key"
description = "Generic API Key"
regex = '''(?i)api[_-]?key[_-]?[=:]\s*['\"]?[0-9a-zA-Z]{20,}['\"]?'''

[allowlist]
paths = [
  "README.md",
  ".gitleaks.toml"
]
`;

    await fs.writeFile(path.join(process.cwd(), '.gitleaks.toml'), gitleaksConfig);
  }

  private async setupVulnerabilityChecks(): Promise<void> {
    const workflowPath = path.join(process.cwd(), '.github', 'workflows', 'security.yml');
    await fs.mkdir(path.dirname(workflowPath), { recursive: true });
    
    const workflow = `name: Security Scan

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]
  schedule:
    - cron: '0 2 * * 1'  # Weekly on Monday

jobs:
  security:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v4
    
    - name: Run Gitleaks
      uses: actions/checkout@v4
    - uses: gitleaks/gitleaks-action@v2
      env:
        GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }}
    
    - name: Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: '18'
        cache: 'npm'
    
    - name: Install dependencies
      run: npm ci
    
    - name: Run npm audit
      run: npm audit --audit-level moderate
`;

    await fs.writeFile(workflowPath, workflow);
  }

  private async setupSecurityGitHooks(): Promise<void> {
    const hookPath = path.join(process.cwd(), '.git', 'hooks', 'pre-commit');
    
    const hook = `#!/bin/sh
# Security pre-commit hook

echo "Running security checks..."

# Check for secrets with gitleaks
if command -v gitleaks >/dev/null 2>&1; then
  gitleaks detect --staged --verbose
  if [ $? -ne 0 ]; then
    echo "❌ Secrets detected! Please remove them before committing."
    exit 1
  fi
else
  echo "⚠️ Gitleaks not installed. Skipping secret detection."
fi

# Run npm audit if package.json exists
if [ -f "package.json" ]; then
  npm audit --audit-level moderate
  if [ $? -ne 0 ]; then
    echo "❌ Security vulnerabilities found! Please fix them before committing."
    exit 1
  fi
fi

echo "✅ Security checks passed!"
`;

    await fs.writeFile(hookPath, hook, { mode: 0o755 });
  }

  private async setupPreCommitConfig(): Promise<void> {
    const config = `repos:
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.16.1
    hooks:
      - id: gitleaks
      
  - repo: local
    hooks:
      - id: npm-audit
        name: npm audit
        entry: npm audit --audit-level moderate
        language: system
        pass_filenames: false
        files: package.json
`;

    await fs.writeFile(path.join(process.cwd(), '.pre-commit-config.yaml'), config);
  }

  async checkDataAccess(options: {
    scanPath: string;
    excludePaths: string[];
    includeWarnings: boolean;
    includeSuggestions: boolean;
  }): Promise<any[]> {
    const violations: any[] = [];
    const atlasAccessPatterns = [
      {
        pattern: /\.atlas\//,
        type: 'Direct Path Access',
        severity: 'high',
        description: 'Direct access to .atlas/ directory detected',
        suggestion: 'Use MCP tools instead of direct file access'
      },
      {
        pattern: /fs\.read.*\(['"`]\.atlas/,
        type: 'File System Read',
        severity: 'critical',
        description: 'Reading .atlas files directly with fs module',
        suggestion: 'Use appropriate MCP tool for data access'
      },
      {
        pattern: /fs\.write.*\(['"`]\.atlas/,
        type: 'File System Write',
        severity: 'critical',
        description: 'Writing to .atlas files directly',
        suggestion: 'Use MCP tools to modify data'
      },
      {
        pattern: /require\(['"`]\.atlas/,
        type: 'Direct Require',
        severity: 'high',
        description: 'Requiring .atlas files directly',
        suggestion: 'Use MCP data access tools'
      },
      {
        pattern: /import.*from ['"`]\.atlas/,
        type: 'Direct Import',
        severity: 'high',
        description: 'Importing from .atlas directory',
        suggestion: 'Use MCP API instead of direct imports'
      },
      {
        pattern: /JSON\.parse.*\.atlas/,
        type: 'Direct JSON Parsing',
        severity: 'medium',
        description: 'Parsing .atlas JSON files directly',
        suggestion: 'Use MCP tools that return parsed data'
      }
    ];

    try {
      await this.scanDirectoryForDataAccess(
        options.scanPath,
        options.excludePaths,
        atlasAccessPatterns,
        violations
      );
    } catch (error) {
      // Handle errors gracefully
    }

    return violations;
  }

  private async scanDirectoryForDataAccess(
    dirPath: string,
    excludePaths: string[],
    patterns: any[],
    violations: any[]
  ): Promise<void> {
    try {
      const items = await fs.readdir(dirPath, { withFileTypes: true });

      for (const item of items) {
        const fullPath = path.join(dirPath, item.name);
        const relativePath = path.relative(process.cwd(), fullPath);

        // Skip excluded paths
        if (excludePaths.some(exclude => relativePath.includes(exclude))) {
          continue;
        }

        if (item.isDirectory()) {
          await this.scanDirectoryForDataAccess(fullPath, excludePaths, patterns, violations);
        } else if (item.isFile() && this.shouldScanForDataAccess(item.name)) {
          await this.scanFileForDataAccess(fullPath, patterns, violations);
        }
      }
    } catch (error) {
      // Skip directories we can't read
    }
  }

  private shouldScanForDataAccess(filename: string): boolean {
    const extensions = ['.js', '.ts', '.jsx', '.tsx', '.mjs', '.cjs'];
    const ext = path.extname(filename).toLowerCase();
    return extensions.includes(ext);
  }

  private async scanFileForDataAccess(
    filePath: string,
    patterns: any[],
    violations: any[]
  ): Promise<void> {
    try {
      const content = await fs.readFile(filePath, 'utf-8');
      const lines = content.split('\n');
      const relativePath = path.relative(process.cwd(), filePath);

      lines.forEach((line, index) => {
        patterns.forEach(patternDef => {
          if (patternDef.pattern.test(line)) {
            violations.push({
              file: relativePath,
              line: index + 1,
              type: patternDef.type,
              severity: patternDef.severity,
              description: patternDef.description,
              suggestion: patternDef.suggestion,
              codeSnippet: line.trim()
            });
          }
        });
      });
    } catch (error) {
      // Skip files we can't read
    }
  }
}