/**
 * @module tests/unit/storage/stats-count-accuracy
 * @description Regression for per-type count inflation. `nounCountsByType` (read by
 * `brain.stats().entitiesByType` and `counts.byTypeEnum`) used to be incremented in
 * `saveNoun_internal()`, which runs on EVERY noun write — including the HNSW index
 * re-saving a node whenever its neighbor links change. So the per-type counts grew
 * with graph connectivity rather than entity count (an internal report saw 8
 * documents read as 44). The counter is now maintained in `saveNounMetadata_internal()`
 * gated on `isNew` + visibility, exactly parallel to the authoritative total — so the
 * per-type counts must equal the entity count EXACTLY, no matter how dense the graph.
 *
 * These assert exact equality on purpose: the prior `toBeGreaterThanOrEqual` style
 * passed for any inflated value and masked the bug.
 */
import { describe, it, expect } from 'vitest'
import { Brainy } from '../../../src/brainy.js'
import { NounType } from '../../../src/types/graphTypes.js'

describe('per-type count accuracy (HNSW re-save inflation)', () => {
  it('stats()/counts report the EXACT entity count for a single dense type', async () => {
    const brain = new Brainy({ requireSubtype: false, storage: { type: 'memory' } })
    await brain.init()
    try {
      // Enough nodes that HNSW links each new node to existing neighbors and
      // re-saves them — the exact path that used to double-count.
      const N = 30
      for (let i = 0; i < N; i++) {
        await brain.add({ data: { name: `person ${i}` }, type: NounType.Person })
      }

      const stats = await brain.stats()
      expect(stats.entityCount).toBe(N)
      expect(stats.entitiesByType[NounType.Person]).toBe(N)
      expect(brain.counts.byTypeEnum(NounType.Person)).toBe(N)
      expect(await brain.getNounCount()).toBe(N)
    } finally {
      await brain.close()
    }
  })

  it('keeps per-type counts exact across multiple types', async () => {
    const brain = new Brainy({ requireSubtype: false, storage: { type: 'memory' } })
    await brain.init()
    try {
      for (let i = 0; i < 12; i++) await brain.add({ data: { n: `p${i}` }, type: NounType.Person })
      for (let i = 0; i < 7; i++) await brain.add({ data: { n: `d${i}` }, type: NounType.Document })

      const stats = await brain.stats()
      expect(stats.entitiesByType[NounType.Person]).toBe(12)
      expect(stats.entitiesByType[NounType.Document]).toBe(7)
      expect(stats.entityCount).toBe(19)
      expect(brain.counts.byTypeEnum(NounType.Person)).toBe(12)
      expect(brain.counts.byTypeEnum(NounType.Document)).toBe(7)
    } finally {
      await brain.close()
    }
  })
})
