import { test } from 'node:test';
import { strict as assert } from 'node:assert';
import { validatePlanContent } from '../../lib/validators/plan-validator.mjs';

const VALID_PLAN = `---
plan_version: "1.7"
---

# Plan

## Implementation Plan

### Step 1: Add foo

- Files: a.ts
- Manifest:
  \`\`\`yaml
  manifest:
    expected_paths:
      - a.ts
    min_file_count: 1
    commit_message_pattern: "^feat:"
    bash_syntax_check: []
    forbidden_paths: []
    must_contain: []
  \`\`\`

### Step 2: Add bar

- Files: b.ts
- Manifest:
  \`\`\`yaml
  manifest:
    expected_paths:
      - b.ts
    min_file_count: 1
    commit_message_pattern: "^feat:"
    bash_syntax_check: []
    forbidden_paths: []
    must_contain: []
  \`\`\`
`;

const FORBIDDEN_PLAN = `---
plan_version: "1.7"
---

## Fase 1: Drift form

content
`;

const STEP_WITHOUT_MANIFEST = `### Step 1: oops
no manifest

### Step 2: ok

- Manifest:
  \`\`\`yaml
  manifest:
    expected_paths: [foo]
    min_file_count: 1
    commit_message_pattern: "^x:"
    bash_syntax_check: []
    forbidden_paths: []
    must_contain: []
  \`\`\`
`;

test('validatePlan — strict accepts canonical v1.7 plan', () => {
  const r = validatePlanContent(VALID_PLAN, { strict: true });
  assert.equal(r.valid, true, JSON.stringify(r.errors));
  assert.equal(r.parsed.steps.length, 2);
  assert.equal(r.parsed.planVersion, '1.7');
});

test('validatePlan — forbidden Fase form blocks in strict mode', () => {
  const r = validatePlanContent(FORBIDDEN_PLAN, { strict: true });
  assert.equal(r.valid, false);
  assert.ok(r.errors.find(e => e.code === 'PLAN_FORBIDDEN_HEADING'));
});

test('validatePlan — manifest count mismatch caught', () => {
  const r = validatePlanContent(STEP_WITHOUT_MANIFEST, { strict: true });
  assert.equal(r.valid, false);
  assert.ok(r.errors.find(e => /Step 1/.test(e.message) && /MANIFEST_MISSING/.test(e.code)));
});

test('validatePlan — version warning when missing', () => {
  const noVersion = VALID_PLAN.replace(/plan_version: "1\.7"\n/, '');
  const r = validatePlanContent(noVersion, { strict: true });
  assert.ok(r.warnings.find(w => w.code === 'PLAN_NO_VERSION'));
});

test('validatePlan — older version triggers warning', () => {
  const old = VALID_PLAN.replace('plan_version: "1.7"', 'plan_version: "1.5"');
  const r = validatePlanContent(old, { strict: true });
  assert.ok(r.warnings.find(w => w.code === 'PLAN_VERSION_MISMATCH'));
});
