/**
 * Regression test: VFS data persists across restart (close + reopen)
 *
 * Verifies the fix for GraphAdjacencyIndex.flush() and LSMTree.get()
 * which previously caused graph relationships to be lost on restart
 * because LSM MemTables were never flushed to SSTables on close.
 */
import { describe, it, expect } from 'vitest'
import { Brainy } from '../../src/brainy.js'
import { VerbType } from '../../src/types/graphTypes.js'
import { mkdirSync, rmSync } from 'fs'

describe('VFS restart persistence', () => {
  it('entities and relationships survive close + reopen', async () => {
    const dir = '/tmp/brainy-restart-fix-' + Date.now()
    mkdirSync(dir, { recursive: true })

    let entityId: string | undefined
    const rootId = '00000000-0000-0000-0000-000000000000'

    try {
      // === SESSION 1: Write data ===
      let brain = new Brainy({ requireSubtype: false,
        storage: { type: 'filesystem', path: dir },
        disableAutoRebuild: true,
        plugins: [],
        silent: true,
      })
      await brain.init()

      await brain.vfs.writeFile('/chapter-1.txt', 'Once upon a time...')

      entityId = await brain.vfs.resolvePathToId('/chapter-1.txt')
      expect(entityId).toBeTruthy()

      // Verify within same session — entity, readdir, and relations
      const entity1 = await brain.get(entityId!)
      expect(entity1).not.toBeNull()

      const entries1 = await brain.vfs.readdir('/')
      expect(entries1.length).toBeGreaterThan(0)

      // In-session related: root should have Contains relationship to the file
      const relations1 = await brain.related({ from: rootId, type: VerbType.Contains })
      expect(relations1.length).toBeGreaterThan(0)

      await brain.close()

      // === SESSION 2: Read data after restart ===
      brain = new Brainy({ requireSubtype: false,
        storage: { type: 'filesystem', path: dir },
        disableAutoRebuild: true,
        plugins: [],
        silent: true,
      })
      await brain.init()

      // Entity should be retrievable
      const entity2 = await brain.get(entityId!)
      expect(entity2).not.toBeNull()

      // Root entity should exist
      const rootEntity = await brain.get(rootId)
      expect(rootEntity).not.toBeNull()

      // readdir should return the file
      const entries2 = await brain.vfs.readdir('/')
      expect(entries2.length).toBeGreaterThan(0)
      expect(entries2).toContain('chapter-1.txt')

      // related should find the Contains relationship
      const relations2 = await brain.related({ from: rootId, type: VerbType.Contains })
      expect(relations2.length).toBeGreaterThan(0)

      await brain.close()
    } finally {
      try { rmSync(dir, { recursive: true }) } catch {}
    }
  })

  it('multiple files and subdirectories survive restart', async () => {
    const dir = '/tmp/brainy-restart-multi-' + Date.now()
    mkdirSync(dir, { recursive: true })

    const rootId = '00000000-0000-0000-0000-000000000000'

    try {
      // === SESSION 1: Write multiple files ===
      let brain = new Brainy({ requireSubtype: false,
        storage: { type: 'filesystem', path: dir },
        disableAutoRebuild: true,
        plugins: [],
        silent: true,
      })
      await brain.init()

      await brain.vfs.writeFile('/readme.txt', 'Project readme')
      await brain.vfs.writeFile('/docs/guide.txt', 'User guide')
      await brain.vfs.writeFile('/docs/api.txt', 'API reference')

      const entries1 = await brain.vfs.readdir('/')
      expect(entries1.length).toBe(2) // readme.txt + docs/

      const docEntries1 = await brain.vfs.readdir('/docs')
      expect(docEntries1.length).toBe(2) // guide.txt + api.txt

      // In-session related: root should have Contains relationships
      const rootRelations1 = await brain.related({ from: rootId, type: VerbType.Contains })
      expect(rootRelations1.length).toBeGreaterThan(0)

      await brain.close()

      // === SESSION 2: Verify all data persisted ===
      brain = new Brainy({ requireSubtype: false,
        storage: { type: 'filesystem', path: dir },
        disableAutoRebuild: true,
        plugins: [],
        silent: true,
      })
      await brain.init()

      // Root children
      const entries2 = await brain.vfs.readdir('/')
      expect(entries2.length).toBe(2)
      expect(entries2.sort()).toEqual(['docs', 'readme.txt'])

      // Subdirectory children
      const docEntries2 = await brain.vfs.readdir('/docs')
      expect(docEntries2.length).toBe(2)
      expect(docEntries2.sort()).toEqual(['api.txt', 'guide.txt'])

      // Root relations
      const rootRelations = await brain.related({ from: rootId, type: VerbType.Contains })
      expect(rootRelations.length).toBeGreaterThan(0)

      await brain.close()
    } finally {
      try { rmSync(dir, { recursive: true }) } catch {}
    }
  })
})
