import { afterEach, describe, expect, it, vi } from 'vitest'

const { appendFileSyncMock, mkdirSyncMock } = vi.hoisted(() => ({
  appendFileSyncMock: vi.fn(),
  mkdirSyncMock: vi.fn(),
}))

vi.mock('node:fs', () => ({
  appendFileSync: appendFileSyncMock,
  mkdirSync: mkdirSyncMock,
}))

const {
  debugLog,
  debugLogSession,
} = await import('../src/dimsdk/core/debug-log.ts')

const realProcess = globalThis.process

function setProcessEnv(env: Record<string, string | undefined>): void {
  Object.defineProperty(globalThis, 'process', {
    configurable: true,
    value: {
      ...realProcess,
      env,
      versions: { node: '22.0.0' },
    },
  })
}

afterEach(() => {
  appendFileSyncMock.mockReset()
  mkdirSyncMock.mockReset()
  Object.defineProperty(globalThis, 'process', {
    configurable: true,
    value: realProcess,
  })
})

describe('debug log helpers', () => {
  it('does not write when debug logging is disabled', () => {
    setProcessEnv({})

    debugLog('event.disabled', { ok: true })

    expect(appendFileSyncMock).not.toHaveBeenCalled()
  })

  it('writes global and session logs when debug logging is enabled', () => {
    setProcessEnv({
      DIMCODE_DEBUG: '1',
      DIMCODE_DEBUG_LOG: '/tmp/dimcode/debug/custom.log',
    })

    debugLog('event.enabled', { ok: true })
    debugLogSession('session/42', 'session.event', { round: 1 })

    expect(mkdirSyncMock).toHaveBeenCalledWith('/tmp/dimcode/debug', {
      recursive: true,
    })
    expect(appendFileSyncMock).toHaveBeenCalledTimes(2)
    expect(appendFileSyncMock.mock.calls[0]?.[0]).toBe('/tmp/dimcode/debug/custom.log')
    expect(String(appendFileSyncMock.mock.calls[0]?.[1] ?? '')).toContain(
      'event.enabled',
    )
    expect(appendFileSyncMock.mock.calls[1]?.[0]).toBe(
      '/tmp/dimcode/debug/session_42.log',
    )
    expect(String(appendFileSyncMock.mock.calls[1]?.[1] ?? '')).toContain(
      'session.event',
    )
  })
})
