/**
 * Empty `find | xargs ls -t` must not fall through to cwd (#2483).
 *
 * GNU xargs runs `ls -t` once even on EMPTY input, and `ls -t` with no
 * operands lists the CURRENT DIRECTORY — so on a fresh install (no
 * ceo-plans / checkpoints / plans yet) a random cwd .md becomes "the plan"
 * or "the latest checkpoint". `xargs -r` pins the BSD skip-on-empty
 * behavior on both GNU and BSD (same shape as the landed
 * bin/gstack-codex-session-import fix, #2482).
 *
 * Re-derived from community PR #2483 by @tranthanhnhatkhoa.
 */
import { describe, test, expect } from 'bun:test';
import { execSync } from 'child_process';
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import { HOST_PATHS } from '../scripts/resolvers/types';
import type { TemplateContext } from '../scripts/resolvers/types';
import { generateContextRecovery } from '../scripts/resolvers/preamble/generate-context-recovery';

const ROOT = path.join(import.meta.dir, '..');

function makeCtx(): TemplateContext {
  return {
    skillName: 'test-skill',
    tmplPath: 'test.tmpl',
    host: 'claude',
    paths: HOST_PATHS.claude,
    preambleTier: 2,
  };
}

describe('empty find must not fall through to cwd (#2483)', () => {
  test('no resolver emits a bare `xargs ls -t` (must be `xargs -r ls -t`)', () => {
    const out = execSync(
      `grep -rn "xargs ls -t" "${path.join(ROOT, 'scripts')}" "${path.join(ROOT, 'bin')}" || true`,
      { encoding: 'utf-8' },
    );
    expect(out.trim()).toBe('');
  });

  test('rendered Context Recovery uses the guarded form at both find sites', () => {
    const rendered = generateContextRecovery(makeCtx());
    const bareSites = rendered.split('xargs ls -t').length - 1;
    expect(bareSites).toBe(0);
    const guardedSites = rendered.split('xargs -r ls -t').length - 1;
    expect(guardedSites).toBe(2);
  });

  test('live block: empty checkpoints dir yields NO checkpoint, not a cwd file', () => {
    const rendered = generateContextRecovery(makeCtx());
    const m = rendered.match(/_LATEST_CP=\$\(.*\)/);
    expect(m).not.toBeNull();
    const line = m![0];

    const home = fs.mkdtempSync(path.join(os.tmpdir(), 'gstack-home-'));
    const cwd = fs.mkdtempSync(path.join(os.tmpdir(), 'gstack-cwd-'));
    try {
      // Fresh install shape: the checkpoints dir exists but is EMPTY,
      // and the cwd holds a decoy markdown file.
      const proj = path.join(home, 'projects', 'unknown');
      fs.mkdirSync(path.join(proj, 'checkpoints'), { recursive: true });
      fs.writeFileSync(path.join(cwd, 'DECOY.md'), '# not a checkpoint\n');

      const script = `_PROJ="${proj}"\n${line.replace(/\$\{_PROJ\}|"\$_PROJ"/g, '"$_PROJ"')}\necho "LATEST_CP=[$_LATEST_CP]"`;
      const out = execSync(`bash -c '${script.replace(/'/g, `'\\''`)}'`, {
        cwd,
        encoding: 'utf-8',
      });
      expect(out).toContain('LATEST_CP=[]');
      expect(out).not.toContain('DECOY.md');
    } finally {
      fs.rmSync(home, { recursive: true, force: true });
      fs.rmSync(cwd, { recursive: true, force: true });
    }
  });

  test('no generated SKILL.md carries the unguarded form', () => {
    const out = execSync(
      `grep -rln "xargs ls -t" --include=SKILL.md "${ROOT}" || true`,
      { encoding: 'utf-8' },
    );
    // node_modules and vendored trees are not generated output; nothing in
    // the repo's generated skills may carry the unguarded form.
    const hits = out
      .split('\n')
      .filter(Boolean)
      .filter((f) => !f.includes('node_modules'))
    // The workspace-local .claude/ install is not generated output and can
    // carry dangling symlinks from unrelated sessions.
    .filter((f) => !f.includes('/.claude/'));
    expect(hits).toEqual([]);
  });
});
