/**
 * Regression test for #2396: hardcoded host-level test commands bypass
 * container-only project Makefiles.
 *
 * Fix: execute-phase.md, verify-phase.md, and audit-fix.md must check for
 * Makefile with a test target (and other wrappers) before falling through
 * to hardcoded language-sniffed commands.
 */

'use strict';

const { describe, test } = require('node:test');
const assert = require('node:assert/strict');
const fs = require('fs');
const path = require('path');

const EXECUTE_PHASE_PATH = path.join(__dirname, '..', 'get-shit-done', 'workflows', 'execute-phase.md');
const VERIFY_PHASE_PATH = path.join(__dirname, '..', 'get-shit-done', 'workflows', 'verify-phase.md');
const AUDIT_FIX_PATH = path.join(__dirname, '..', 'get-shit-done', 'workflows', 'audit-fix.md');

function assertMakefileCheckBeforeNpmTest(filePath, label) {
  const content = fs.readFileSync(filePath, 'utf-8');

  // Must check for Makefile with test target
  const hasMakefileCheck = /Makefile.*grep.*test:|grep.*test:.*Makefile/s.test(content) ||
    (content.includes('Makefile') && content.includes('"^test:"'));
  assert.ok(
    hasMakefileCheck,
    `${label}: must check for Makefile with test: target before falling through to hardcoded commands`
  );

  // make test must appear before npm test in the file
  const makeTestIdx = content.indexOf('make test');
  const npmTestIdx = content.indexOf('npm test');
  assert.ok(makeTestIdx !== -1, `${label}: must contain "make test"`);
  assert.ok(npmTestIdx !== -1, `${label}: must still contain "npm test" as fallback`);
  assert.ok(
    makeTestIdx < npmTestIdx,
    `${label}: "make test" must appear before "npm test" (Makefile takes priority)`
  );
}

function assertConfigGetBeforeMakefile(filePath, label) {
  const content = fs.readFileSync(filePath, 'utf-8');
  // Must check workflow.test_command config before Makefile sniff.
  // Verify within each bash code block: the workflow.test_command lookup
  // appears before the Makefile grep in the same block.
  assert.ok(
    content.includes('workflow.test_command'),
    `${label}: must check workflow.test_command config before Makefile/language sniff`
  );

  // Extract bash blocks to check ordering within each block.
  // Use the actual Makefile test ([ -f "Makefile" ]) not just the word "Makefile"
  // (which appears in comments before the config-get call).
  const bashBlockRe = /```bash([\s\S]*?)```/g;
  let match;
  let anyBlockCorrectlyOrdered = false;
  while ((match = bashBlockRe.exec(content)) !== null) {
    const block = match[1];
    if (block.includes('workflow.test_command') && block.includes('[ -f "Makefile"')) {
      const configIdx = block.indexOf('workflow.test_command');
      const makefileIdx = block.indexOf('[ -f "Makefile"');
      if (configIdx < makefileIdx) {
        anyBlockCorrectlyOrdered = true;
        break;
      }
    }
  }
  assert.ok(
    anyBlockCorrectlyOrdered,
    `${label}: within a bash block, workflow.test_command config check must appear before Makefile test ([ -f "Makefile" ])`
  );
}

describe('bug-2396: Makefile test target must take priority over hardcoded commands', () => {
  test('execute-phase.md exists', () => {
    assert.ok(fs.existsSync(EXECUTE_PHASE_PATH), 'execute-phase.md should exist');
  });

  test('verify-phase.md exists', () => {
    assert.ok(fs.existsSync(VERIFY_PHASE_PATH), 'verify-phase.md should exist');
  });

  test('audit-fix.md exists', () => {
    assert.ok(fs.existsSync(AUDIT_FIX_PATH), 'audit-fix.md should exist');
  });

  test('execute-phase.md: Makefile check precedes npm test (post-merge gate)', () => {
    assertMakefileCheckBeforeNpmTest(EXECUTE_PHASE_PATH, 'execute-phase.md');
  });

  test('verify-phase.md: Makefile check precedes npm test', () => {
    assertMakefileCheckBeforeNpmTest(VERIFY_PHASE_PATH, 'verify-phase.md');
  });

  test('audit-fix.md: Makefile check precedes npm test', () => {
    assertMakefileCheckBeforeNpmTest(AUDIT_FIX_PATH, 'audit-fix.md');
  });

  test('execute-phase.md: workflow.test_command config checked first (within bash block)', () => {
    assertConfigGetBeforeMakefile(EXECUTE_PHASE_PATH, 'execute-phase.md');
  });

  test('verify-phase.md: workflow.test_command config checked first (within bash block)', () => {
    assertConfigGetBeforeMakefile(VERIFY_PHASE_PATH, 'verify-phase.md');
  });

  test('audit-fix.md: workflow.test_command config checked first (within bash block)', () => {
    assertConfigGetBeforeMakefile(AUDIT_FIX_PATH, 'audit-fix.md');
  });
});
