import { describe, it, expect } from 'vitest';
import { computeDiff, countChanges } from '../../../src/utils/diff.js';

describe('Diff - 差异比较扩展测试', () => {
  describe('computeDiff - 计算 diff', () => {
    it('新文件所有行都是添加', () => {
      const diff = computeDiff(null, 'line1\nline2\nline3');

      expect(diff.isNew).toBe(true);
      expect(diff.oldContent).toBeNull();
      expect(diff.hunks.length).toBe(1);
      expect(diff.hunks[0].lines.every(l => l.type === 'add')).toBe(true);
      expect(diff.hunks[0].newCount).toBe(3);
    });

    it('相同内容返回空 hunks', () => {
      const content = 'line1\nline2\nline3';
      const diff = computeDiff(content, content);

      expect(diff.isNew).toBe(false);
      // 相同内容可能没有实际变化的 hunks
      const hasChanges = diff.hunks.some(h =>
        h.lines.some(l => l.type === 'add' || l.type === 'remove')
      );
      expect(hasChanges).toBe(false);
    });

    it('检测添加的行', () => {
      const oldContent = 'line1\nline2';
      const newContent = 'line1\nline2\nline3';
      const diff = computeDiff(oldContent, newContent);

      expect(diff.isNew).toBe(false);
      const addedLines = diff.hunks.flatMap(h => h.lines.filter(l => l.type === 'add'));
      expect(addedLines.some(l => l.content === 'line3')).toBe(true);
    });

    it('检测删除的行', () => {
      const oldContent = 'line1\nline2\nline3';
      const newContent = 'line1\nline2';
      const diff = computeDiff(oldContent, newContent);

      const removedLines = diff.hunks.flatMap(h => h.lines.filter(l => l.type === 'remove'));
      expect(removedLines.some(l => l.content === 'line3')).toBe(true);
    });

    it('检测修改的行（删除+添加）', () => {
      const oldContent = 'line1\nold line\nline3';
      const newContent = 'line1\nnew line\nline3';
      const diff = computeDiff(oldContent, newContent);

      const removedLines = diff.hunks.flatMap(h => h.lines.filter(l => l.type === 'remove'));
      const addedLines = diff.hunks.flatMap(h => h.lines.filter(l => l.type === 'add'));

      expect(removedLines.some(l => l.content === 'old line')).toBe(true);
      expect(addedLines.some(l => l.content === 'new line')).toBe(true);
    });

    it('处理空文件', () => {
      const diff = computeDiff('', 'new content');

      expect(diff.isNew).toBe(false);
      // 空到有内容是添加
      const addedLines = diff.hunks.flatMap(h => h.lines.filter(l => l.type === 'add'));
      expect(addedLines.length).toBeGreaterThan(0);
    });

    it('处理多个不连续的变更', () => {
      const oldContent = 'line1\nkeep1\nold2\nkeep2\nold3\nline6';
      const newContent = 'line1\nkeep1\nnew2\nkeep2\nnew3\nline6';
      const diff = computeDiff(oldContent, newContent);

      // 应该有变更
      const changes = diff.hunks.flatMap(h =>
        h.lines.filter(l => l.type === 'add' || l.type === 'remove')
      );
      expect(changes.length).toBeGreaterThan(0);
    });

    it('处理完全不同的内容', () => {
      const oldContent = 'completely\ndifferent\ncontent';
      const newContent = 'totally\nnew\nstuff';
      const diff = computeDiff(oldContent, newContent);

      expect(diff.hunks.length).toBeGreaterThan(0);
    });
  });

  describe('countChanges - 统计变更', () => {
    it('统计添加行数', () => {
      const diff = computeDiff(null, 'line1\nline2\nline3');
      const changes = countChanges(diff);

      expect(changes.additions).toBe(3);
      expect(changes.deletions).toBe(0);
    });

    it('统计删除行数', () => {
      const diff = computeDiff('line1\nline2\nline3', '');
      const changes = countChanges(diff);

      expect(changes.deletions).toBe(3);
    });

    it('统计混合变更', () => {
      const diff = computeDiff('old1\nold2', 'new1\nold2\nnew2');
      const changes = countChanges(diff);

      // 具体数字取决于 diff 算法实现
      expect(changes.additions).toBeGreaterThanOrEqual(0);
      expect(changes.deletions).toBeGreaterThanOrEqual(0);
    });

    it('无变更返回零', () => {
      const diff = computeDiff('same', 'same');
      const changes = countChanges(diff);

      expect(changes.additions + changes.deletions).toBe(0);
    });
  });
});
