#!/usr/bin/env ts-node
// arch-guard.ts — Pre-commit hook: enforces {{ARCHITECTURE}} import boundaries
// Generated for {{PROJECT_NAME}} ({{ARCHITECTURE}} architecture)

import * as fs from 'fs';
import * as path from 'path';
import { execSync } from 'child_process';

const RED    = '\x1b[31m';
const YELLOW = '\x1b[33m';
const GREEN  = '\x1b[32m';
const RESET  = '\x1b[0m';

interface ArchRule {
  sourcePattern: RegExp;
  forbiddenImports: RegExp[];
  message: string;
}

// Architecture-specific rules for {{ARCHITECTURE}}
const ARCH_RULES: ArchRule[] = [
  ...getArchRules()
];

function getArchRules(): ArchRule[] {
  const arch = '{{ARCH_RAW}}';

  if (arch === 'clean') {
    return [
      {
        sourcePattern: /features\/\w+\/domain\//,
        forbiddenImports: [/features\/\w+\/data\//, /features\/\w+\/presentation\//],
        message: 'domain/ must not import from data/ or presentation/',
      },
      {
        sourcePattern: /features\/\w+\/presentation\//,
        forbiddenImports: [/features\/\w+\/data\//],
        message: 'presentation/ must not import from data/ directly (use domain interfaces)',
      },
    ];
  }

  if (arch === 'feature_first') {
    return [
      {
        // A feature file must not import from another feature
        sourcePattern: /features\/(\w+)\//,
        forbiddenImports: [], // checked dynamically below
        message: 'Features must not import from other feature folders',
      },
    ];
  }

  if (arch === 'mvvm') {
    return [
      {
        sourcePattern: /viewmodels\//,
        forbiddenImports: [/package:flutter\//, /widgets\//],
        message: 'ViewModels must not import Flutter widgets — they must be plain Dart testable',
      },
    ];
  }

  return [];
}

function getChangedDartFiles(): string[] {
  try {
    const result = execSync('git diff --cached --name-only --diff-filter=ACM', { encoding: 'utf8' });
    return result.split('\n').filter(f => f.endsWith('.dart') && fs.existsSync(f));
  } catch {
    return [];
  }
}

function checkFile(filePath: string): string[] {
  const violations: string[] = [];
  const content = fs.readFileSync(filePath, 'utf8');
  const imports = content.match(/^import\s+'[^']+'/gm) ?? [];

  for (const rule of ARCH_RULES) {
    if (!rule.sourcePattern.test(filePath)) continue;

    // Feature-first cross-feature check
    if ('{{ARCH_RAW}}' === 'feature_first') {
      const srcFeatureMatch = filePath.match(/features\/(\w+)\//);
      if (srcFeatureMatch) {
        const srcFeature = srcFeatureMatch[1];
        for (const imp of imports) {
          const impFeatureMatch = imp.match(/features\/(\w+)\//);
          if (impFeatureMatch && impFeatureMatch[1] !== srcFeature) {
            violations.push(
              `${RED}ARCH VIOLATION${RESET} in ${filePath}:\n` +
              `  ${YELLOW}${rule.message}${RESET}\n` +
              `  Import: ${imp}\n` +
              `  Fix: Move shared code to core/ or shared/`
            );
          }
        }
      }
      continue;
    }

    // Standard forbidden import check
    for (const imp of imports) {
      for (const forbidden of rule.forbiddenImports) {
        if (forbidden.test(imp)) {
          violations.push(
            `${RED}ARCH VIOLATION${RESET} in ${filePath}:\n` +
            `  ${YELLOW}${rule.message}${RESET}\n` +
            `  Import: ${imp}`
          );
        }
      }
    }
  }

  return violations;
}

const changedFiles = getChangedDartFiles();
if (changedFiles.length === 0) {
  console.log(`${GREEN}✔ arch-guard: no Dart files changed${RESET}`);
  process.exit(0);
}

console.log(`🏛  arch-guard checking ${changedFiles.length} file(s) for {{ARCHITECTURE}} violations...`);

const allViolations: string[] = [];
for (const file of changedFiles) {
  allViolations.push(...checkFile(file));
}

if (allViolations.length > 0) {
  console.error(`\n${RED}✘ Architecture boundary violations detected:${RESET}\n`);
  for (const v of allViolations) console.error(v + '\n');
  console.error(`Total: ${allViolations.length} violation(s). Fix before committing.`);
  process.exit(1);
}

console.log(`${GREEN}✔ arch-guard: no violations found${RESET}`);
