import { describe, it, expect } from 'vitest';
import { computeDiff, applyDiff } from '../../src/utils/text-differ.js';

describe('text-differ', () => {
  describe('computeDiff', () => {
    it('returns empty patches for identical content', () => {
      const lines = ['a', 'b', 'c'];
      expect(computeDiff(lines, lines)).toEqual([]);
    });

    it('detects a single line change', () => {
      const oldLines = ['a', 'b', 'c'];
      const newLines = ['a', 'B', 'c'];
      const patches = computeDiff(oldLines, newLines);

      expect(patches.length).toBe(1);
      expect(patches[0].startLine).toBe(1);
      expect(patches[0].deleteCount).toBe(1);
      expect(patches[0].insertLines).toEqual(['B']);
    });

    it('detects added lines', () => {
      const oldLines = ['a', 'b'];
      const newLines = ['a', 'b', 'c', 'd'];
      const patches = computeDiff(oldLines, newLines);

      expect(patches.length).toBeGreaterThan(0);
      const result = applyDiff(oldLines, patches);
      expect(result).toEqual(newLines);
    });

    it('detects removed lines', () => {
      const oldLines = ['a', 'b', 'c', 'd'];
      const newLines = ['a', 'd'];
      const patches = computeDiff(oldLines, newLines);

      const result = applyDiff(oldLines, patches);
      expect(result).toEqual(newLines);
    });
  });

  describe('applyDiff', () => {
    it('applies patches to reconstruct new content', () => {
      const old = ['line1', 'line2', 'line3', 'line4', 'line5'];
      const now = ['line1', 'CHANGED', 'line3', 'ADDED', 'line4', 'line5'];

      const patches = computeDiff(old, now);
      const result = applyDiff(old, patches);
      expect(result).toEqual(now);
    });

    it('handles empty old lines', () => {
      const patches = computeDiff([], ['a', 'b']);
      const result = applyDiff([], patches);
      expect(result).toEqual(['a', 'b']);
    });

    it('handles empty new lines', () => {
      const patches = computeDiff(['a', 'b'], []);
      const result = applyDiff(['a', 'b'], patches);
      expect(result).toEqual([]);
    });
  });
});
