import fs from 'fs';
import path from 'path';
import { describe, expect, it, vi } from 'vitest';
import { createFileAction, revertSpaceInitAction } from '@/lib/actions';
import { getTestMindRoot } from '../setup';

vi.mock('next/cache', () => ({
  revalidatePath: vi.fn(),
}));

describe('revertSpaceInitAction path safety', () => {
  it('does not write scaffold files outside MIND_ROOT via sibling-prefix traversal', async () => {
    const root = getTestMindRoot();
    const outsideDir = `${root}-outside`;
    fs.mkdirSync(outsideDir, { recursive: true });

    try {
      const traversalPath = path.relative(root, outsideDir);
      const result = await revertSpaceInitAction(traversalPath, 'Outside', 'Should not write');

      expect(result.success).toBe(false);
      expect(fs.existsSync(path.join(outsideDir, 'README.md'))).toBe(false);
      expect(fs.existsSync(path.join(outsideDir, 'INSTRUCTION.md'))).toBe(false);
    } finally {
      fs.rmSync(outsideDir, { recursive: true, force: true });
    }
  });

  it('does not write scaffold files through a symlinked space outside MIND_ROOT', async () => {
    const root = getTestMindRoot();
    const outsideDir = `${root}-outside`;
    fs.mkdirSync(outsideDir, { recursive: true });
    fs.symlinkSync(outsideDir, path.join(root, 'Linked'), 'dir');

    try {
      const result = await revertSpaceInitAction('Linked', 'Outside', 'Should not write');

      expect(result.success).toBe(false);
      expect(fs.existsSync(path.join(outsideDir, 'README.md'))).toBe(false);
      expect(fs.existsSync(path.join(outsideDir, 'INSTRUCTION.md'))).toBe(false);
    } finally {
      fs.rmSync(outsideDir, { recursive: true, force: true });
    }
  });
});

describe('createFileAction path safety', () => {
  it('rejects file names that escape the selected directory', async () => {
    const root = getTestMindRoot();
    fs.mkdirSync(path.join(root, 'Selected'), { recursive: true });

    const result = await createFileAction('Selected', '../evil.md');

    expect(result.success).toBe(false);
    expect(fs.existsSync(path.join(root, 'evil.md'))).toBe(false);
  });
});
