/**
 * Tripwire: the npm-publish workflow must NOT re-introduce
 * `javascript-obfuscator` or any other source-modifying step that
 * would defeat the explicit decision in commit removing obfuscation.
 *
 * If you genuinely want to bring obfuscation back, change this test
 * AND record the rationale in the workflow's leading comment block.
 * Don't just delete the test.
 */

import { describe, test, expect } from '@jest/globals';
import { readFileSync, readdirSync } from 'node:fs';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';

const __dirname = dirname(fileURLToPath(import.meta.url));
const REPO_ROOT = join(__dirname, '..', '..');
const WORKFLOWS_DIR = join(REPO_ROOT, '.github', 'workflows');

const FORBIDDEN_IN_PUBLISH = [
  'javascript-obfuscator',
  'javascript_obfuscator',
];

describe('release workflows — obfuscation absence', () => {
  test('publish-npm-trusted.yml contains no obfuscator install or invocation', () => {
    const yaml = readFileSync(join(WORKFLOWS_DIR, 'publish-npm-trusted.yml'), 'utf8');
    for (const needle of FORBIDDEN_IN_PUBLISH) {
      // Tolerate the literal mention inside a comment block that
      // documents the removal — but not in any other context.
      const lines = yaml.split('\n');
      const offending = lines
        .map((line, idx) => ({ line, idx }))
        .filter(({ line }) => line.includes(needle))
        .filter(({ line }) => !/^\s*#/.test(line) && !/^\s*\/\//.test(line));
      expect(offending).toEqual([]);
    }
  });

  test('workflow YAML is syntactically valid (no orphaned steps)', () => {
    const yaml = readFileSync(join(WORKFLOWS_DIR, 'publish-npm-trusted.yml'), 'utf8');
    // We don't bundle a YAML parser into the CLI repo; a structural
    // smoke test is enough to catch the most common form of breakage
    // (deleting a step without removing the leading `- name:`).
    const stepCount = (yaml.match(/^\s{4,6}- name:/gm) || []).length;
    expect(stepCount).toBeGreaterThan(5);
    // Each top-level step name should be followed by either `run:` or `uses:`
    const lines = yaml.split('\n');
    let pendingStepLine = null;
    for (let i = 0; i < lines.length; i++) {
      if (/^\s{4,6}- name:/.test(lines[i])) {
        pendingStepLine = i;
      } else if (pendingStepLine != null && /^\s{6,8}(run|uses):/.test(lines[i])) {
        pendingStepLine = null;
      } else if (pendingStepLine != null && /^\s{4,6}- /.test(lines[i])) {
        throw new Error(`step at line ${pendingStepLine + 1} has no run/uses`);
      }
    }
  });

  test('every yml file in .github/workflows parses (basic balance check)', () => {
    const files = readdirSync(WORKFLOWS_DIR).filter(f => f.endsWith('.yml') || f.endsWith('.yaml'));
    expect(files.length).toBeGreaterThan(0);
    for (const f of files) {
      const yaml = readFileSync(join(WORKFLOWS_DIR, f), 'utf8');
      // Naive but useful: every workflow should have `jobs:` and at
      // least one step.
      expect(yaml).toMatch(/^jobs:/m);
      expect(yaml).toMatch(/^\s+steps:/m);
    }
  });
});
