/**
 * reconciler-wiring.test.ts
 *
 * A2aTaskReconciler のライフサイクル（start/stop）を fake timers で検証。
 * server.ts への結線は Task 6 の e2e テストで確認するため、ここは reconciler
 * 単体に留める。
 */

import { describe, it, expect, vi, afterEach } from 'vitest';
import { A2aTaskReconciler } from './reconciler.js';

afterEach(() => {
  vi.useRealTimers();
});

describe('A2aTaskReconciler lifecycle', () => {
  it('start() triggers an immediate reconcile tick', async () => {
    vi.useFakeTimers();

    let callCount = 0;
    const fakeRepo = {
      listNonTerminalA2aTasks: () => { callCount++; return []; },
    } as any;

    const reconciler = new A2aTaskReconciler({ repo: fakeRepo, intervalMs: 1000 });
    reconciler.start();

    // Drain the microtask queue so the immediate async tick completes.
    await Promise.resolve();

    expect(callCount).toBeGreaterThanOrEqual(1);
  });

  it('periodic interval fires after intervalMs', async () => {
    vi.useFakeTimers();

    let callCount = 0;
    const fakeRepo = {
      listNonTerminalA2aTasks: () => { callCount++; return []; },
    } as any;

    const reconciler = new A2aTaskReconciler({ repo: fakeRepo, intervalMs: 1000 });
    reconciler.start();

    // Drain immediate tick.
    await Promise.resolve();
    const afterStart = callCount;

    // Advance one full interval.
    await vi.advanceTimersByTimeAsync(1000);

    expect(callCount).toBeGreaterThan(afterStart);
  });

  it('stop() prevents further ticks after interval advances', async () => {
    vi.useFakeTimers();

    let callCount = 0;
    const fakeRepo = {
      listNonTerminalA2aTasks: () => { callCount++; return []; },
    } as any;

    const reconciler = new A2aTaskReconciler({ repo: fakeRepo, intervalMs: 1000 });
    reconciler.start();

    // Drain immediate tick.
    await Promise.resolve();

    reconciler.stop();
    const countAfterStop = callCount;

    // Advance several intervals — the cleared timer must not fire.
    await vi.advanceTimersByTimeAsync(5000);

    expect(callCount).toBe(countAfterStop);
  });

  it('double start() does not leak a second interval', async () => {
    vi.useFakeTimers();

    let callCount = 0;
    const fakeRepo = {
      listNonTerminalA2aTasks: () => { callCount++; return []; },
    } as any;

    const reconciler = new A2aTaskReconciler({ repo: fakeRepo, intervalMs: 1000 });
    reconciler.start();
    reconciler.start(); // should replace, not add

    await Promise.resolve();
    const afterDoubleStart = callCount;

    await vi.advanceTimersByTimeAsync(1000);

    // Only one interval should fire; if two leaked, callCount would jump by 2.
    expect(callCount).toBe(afterDoubleStart + 1);

    reconciler.stop();
  });
});
