/**
 * @module tests/unit/storage/getVerbs-totalCount
 * @description Verb-side mirror of getNouns-totalCount (the b2005ff fix). The
 * verb type-scan pagination (`BaseStorage.getVerbsWithPagination`) early-terminates
 * at `offset + limit + 1` (it peeks one extra item to compute `hasMore`), then
 * returned `collectedVerbs.length` as `totalCount` — i.e. the PAGE size, never the
 * dataset total. So `getVerbs({ pagination: { limit: 1 } }).totalCount` reported 1
 * (or 2) for any non-empty brain on the unfiltered path. `totalCount` must be the
 * authoritative O(1) verb counter (`totalVerbCount`, isNew-gated +
 * visibility-filtered, rehydrated from `counts.json` on init).
 */
import { describe, it, expect } from 'vitest'
import { mkdtempSync, rmSync } from 'fs'
import { tmpdir } from 'os'
import { join } from 'path'
import { FileSystemStorage } from '../../../src/storage/adapters/fileSystemStorage.js'
import type { VerbMetadata, HNSWVerb } from '../../../src/coreTypes.js'
import { VerbType } from '../../../src/types/graphTypes.js'

const DIM = 8

/** A deterministic non-zero vector so the verb record is well-formed. */
function vec(seed: number): number[] {
  return Array.from({ length: DIM }, (_, i) => ((seed + i) % 7) / 7 - 0.5)
}

/** Storage shards by UUID, so ids must be 32 hex chars. */
function uuid(i: number, salt = 0): string {
  return (i + salt).toString(16).padStart(32, '0')
}

/**
 * Seed `n` unique verbs. Metadata is saved BEFORE the verb record: it is where
 * the O(1) verb counter is incremented (isNew-gated), mirroring the real
 * relate() path.
 */
async function seed(storage: FileSystemStorage, n: number): Promise<void> {
  for (let i = 0; i < n; i++) {
    const id = uuid(i, 0x1000)
    const sourceId = uuid(i, 0x4000)
    const targetId = uuid(i, 0x8000)
    await storage.saveVerbMetadata(id, {
      verb: VerbType.RelatedTo,
      sourceId,
      targetId,
      createdAt: Date.now(),
      updatedAt: Date.now()
    } as VerbMetadata)
    await storage.saveVerb({
      id,
      vector: vec(i),
      connections: new Map(),
      verb: VerbType.RelatedTo,
      sourceId,
      targetId
    } as HNSWVerb)
  }
}

describe('FileSystemStorage.getVerbs totalCount (verb mirror of b2005ff)', () => {
  it('reports the TRUE total, not the page size, for a 1-item page', async () => {
    const dir = mkdtempSync(join(tmpdir(), 'brainy-verbtotal-'))
    try {
      const storage = new FileSystemStorage(dir)
      await storage.init()
      await seed(storage, 25)

      const onePage = await storage.getVerbs({ pagination: { limit: 1 } })
      expect(onePage.items.length).toBe(1)
      // Before the fix this was the peeked page size (limit + 1 == 2).
      expect(onePage.totalCount).toBe(25)
      expect(onePage.hasMore).toBe(true)
    } finally {
      rmSync(dir, { recursive: true, force: true })
    }
  })

  it('still reports the true total after a cold reopen (counts rehydrate)', async () => {
    const dir = mkdtempSync(join(tmpdir(), 'brainy-verbtotal-reopen-'))
    try {
      const first = new FileSystemStorage(dir)
      await first.init()
      await seed(first, 25)
      await (first as unknown as { persistCounts(): Promise<void> }).persistCounts()

      const reopened = new FileSystemStorage(dir)
      await reopened.init()
      const page = await reopened.getVerbs({ pagination: { limit: 1 } })
      expect(page.totalCount).toBe(25)
    } finally {
      rmSync(dir, { recursive: true, force: true })
    }
  })
})
