// Copyright (C) 2026 Garudex Labs.  All Rights Reserved.
// Caracal, a product of Garudex Labs
//
// Retention cleaner unit tests covering lock gating and terminal row pruning.

import { describe, expect, it, vi } from 'vitest'
import '../../../../../shared/test-utils/typescript/coordinatorEnv.js'
import { runRetentionCleanup } from '../../../../../../apps/coordinator/src/jobs/retention-cleaner.js'

function clientWithRows(rows: Array<{ rowCount?: number; rows?: unknown[] }>) {
  return {
    query: vi.fn(async () => rows.shift() ?? { rows: [], rowCount: 0 }),
    release: vi.fn(),
  }
}

describe('runRetentionCleanup', () => {
  it('skips cleanup when another replica holds the lock', async () => {
    const client = clientWithRows([
      { rows: [] },
      { rows: [{ acquired: false }] },
      { rows: [] },
    ])
    const db = { connect: vi.fn().mockResolvedValueOnce(client) }
    await expect(runRetentionCleanup(db as never)).resolves.toEqual({
      expiredEdges: 0,
      deletedEdges: 0,
      deletedOutbox: 0,
    })
    expect(client.query).toHaveBeenCalledWith('ROLLBACK')
    expect(client.query).not.toHaveBeenCalledWith(expect.stringContaining('DELETE FROM delegation_edges'), expect.anything())
  })

  it('expires active edges, invalidates delegation caches, and prunes terminal rows', async () => {
    const client = clientWithRows([
      { rows: [] },
      { rows: [{ acquired: true }] },
      {
        rows: [
          { id: 'edge-1', zone_id: 'z1', source_session_id: 's1', target_session_id: 's2' },
          { id: 'edge-2', zone_id: 'z1', source_session_id: 's2', target_session_id: 's3' },
        ],
      },
      { rows: [{ epoch: '7' }] },
      { rows: [] },
      { rowCount: 3 },
      { rowCount: 4 },
      { rows: [] },
    ])
    const db = { connect: vi.fn().mockResolvedValueOnce(client) }
    await expect(runRetentionCleanup(db as never)).resolves.toEqual({
      expiredEdges: 2,
      deletedEdges: 3,
      deletedOutbox: 4,
    })
    expect(client.query).toHaveBeenCalledWith(expect.stringContaining("status = 'expired'"), [500])
    expect(client.query).toHaveBeenCalledWith(expect.stringContaining('RETURNING epoch'), ['z1'])
    expect(client.query).toHaveBeenCalledWith(
      expect.stringContaining('INSERT INTO caracal_outbox'),
      expect.arrayContaining([
        'caracal.delegations.invalidate',
        'edge_expire:z1:7',
        expect.objectContaining({
          event: 'edge_expire',
          zone_id: 'z1',
          affected_edges: 2,
          edge_ids: ['edge-1', 'edge-2'],
          epoch: 7,
        }),
      ]),
    )
    expect(client.query).toHaveBeenCalledWith(expect.stringContaining('DELETE FROM delegation_edges d'), [90, 500])
    expect(client.query).toHaveBeenCalledWith(expect.stringContaining('DELETE FROM caracal_outbox o'), [7, 500])
    expect(client.query).toHaveBeenCalledWith('COMMIT')
  })
})
