import { describe, it, expect, vi, beforeEach } from 'vitest';
import { GitClient } from '../../src/main/services/GitClient.js';

describe('GitClient — fetch / rebase / conflict 메서드', () => {
  let client: GitClient;
  let runSpy: ReturnType<typeof vi.spyOn>;

  beforeEach(() => {
    client = new GitClient('/tmp/sync');
    runSpy = vi.spyOn(client, 'run');
  });

  it('fetch — git fetch origin 호출', async () => {
    runSpy.mockResolvedValueOnce({ stdout: '', stderr: '', exitCode: 0 });
    const r = await client.fetch();
    expect(runSpy).toHaveBeenCalledWith(['fetch', 'origin']);
    expect(r.exitCode).toBe(0);
  });

  it('rebaseOnto — git rebase origin/main', async () => {
    runSpy.mockResolvedValueOnce({ stdout: '', stderr: '', exitCode: 0 });
    const r = await client.rebaseOnto('origin/main');
    expect(runSpy).toHaveBeenCalledWith(['rebase', 'origin/main']);
    expect(r.exitCode).toBe(0);
  });

  it('rebaseAbort — git rebase --abort', async () => {
    runSpy.mockResolvedValueOnce({ stdout: '', stderr: '', exitCode: 0 });
    await client.rebaseAbort();
    expect(runSpy).toHaveBeenCalledWith(['rebase', '--abort']);
  });

  it('hasUncommittedChanges — git status --porcelain 의 출력 있으면 true', async () => {
    runSpy.mockResolvedValueOnce({ stdout: ' M notes/abc.md\n', stderr: '', exitCode: 0 });
    expect(await client.hasUncommittedChanges()).toBe(true);

    runSpy.mockResolvedValueOnce({ stdout: '', stderr: '', exitCode: 0 });
    expect(await client.hasUncommittedChanges()).toBe(false);
  });

  it('listConflicts — git diff --name-only --diff-filter=U 결과 파싱', async () => {
    runSpy.mockResolvedValueOnce({
      stdout: 'notes/aaa.md\nnotes/bbb.md\n',
      stderr: '',
      exitCode: 0
    });
    const r = await client.listConflicts();
    expect(runSpy).toHaveBeenCalledWith(['diff', '--name-only', '--diff-filter=U']);
    expect(r).toEqual(['notes/aaa.md', 'notes/bbb.md']);
  });
});
