import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach, describe, expect, it } from 'vitest'
import {
  getDimcodeConfigDir,
  getDimcodeUserDir,
  loadDimcodeUserCache,
  saveDimcodeUserCache,
} from '../src/dimsdk/core/config.ts'

const tempHomes: string[] = []

async function withHome<T>(home: string, run: () => Promise<T>): Promise<T> {
  const prev = process.env.HOME
  process.env.HOME = home
  try {
    return await run()
  }
  finally {
    if (prev == null)
      delete process.env.HOME
    else
      process.env.HOME = prev
  }
}

afterEach(() => {
  while (tempHomes.length > 0) {
    rmSync(tempHomes.pop() as string, { force: true, recursive: true })
  }
})

describe('core config helpers', () => {
  it('resolves dimcode config and user dirs from process env', async () => {
    const home = mkdtempSync(`${tmpdir()}/best-agent-core-config-`)
    tempHomes.push(home)

    await withHome(home, async () => {
      await expect(getDimcodeConfigDir()).resolves.toBe(join(home, '.dimcode'))
      await expect(getDimcodeUserDir()).resolves.toBe(
        join(home, '.dimcode', 'dimcode'),
      )
    })
  })

  it('round-trips cache files and ignores non-v1 payloads', async () => {
    const home = mkdtempSync(`${tmpdir()}/best-agent-core-cache-`)
    tempHomes.push(home)

    await withHome(home, async () => {
      const filePath = join(home, '.dimcode', 'dimcode', 'cache.json')
      await saveDimcodeUserCache(filePath, {
        version: 1,
        updatedAt: 42,
        settings: {
          model: 'gpt-5',
        },
      })

      const loaded = await loadDimcodeUserCache()
      expect(loaded.cache).toEqual({
        version: 1,
        updatedAt: 42,
        settings: {
          model: 'gpt-5',
        },
      })

      mkdirSync(join(home, '.dimcode', 'dimcode'), { recursive: true })
      writeFileSync(filePath, JSON.stringify({ version: 2, updatedAt: 99 }), 'utf8')

      const fallback = await loadDimcodeUserCache()
      expect(fallback.cache).toEqual({ version: 1, updatedAt: 0 })
    })
  })
})
