import test from 'node:test'
import assert from 'node:assert/strict'

import {
  formatLogEntry,
  formatLogTimestamp,
  normalizeLogLevel,
  resolveExpiredLogFilenames,
  resolveLogFilePath,
  shouldWriteLog,
} from './logger.js'

test('normalizeLogLevel falls back to info for unsupported values', () => {
  assert.equal(normalizeLogLevel('debug'), 'debug')
  assert.equal(normalizeLogLevel('WARN'), 'warn')
  assert.equal(normalizeLogLevel('verbose'), 'info')
  assert.equal(normalizeLogLevel(''), 'info')
})

test('shouldWriteLog respects configured minimum log level', () => {
  assert.equal(shouldWriteLog('debug', 'debug'), true)
  assert.equal(shouldWriteLog('info', 'debug'), true)
  assert.equal(shouldWriteLog('debug', 'info'), false)
  assert.equal(shouldWriteLog('info', 'warn'), false)
  assert.equal(shouldWriteLog('warn', 'warn'), true)
  assert.equal(shouldWriteLog('error', 'warn'), true)
})

test('resolveLogFilePath uses daily log file names by channel', () => {
  assert.match(resolveLogFilePath('app', '2026-04-14T10:00:00.000Z'), /app-2026-04-14\.log$/)
  assert.match(resolveLogFilePath('webhook', '2026-04-14T10:00:00.000Z'), /webhook-2026-04-14\.log$/)
})

test('resolveExpiredLogFilenames keeps latest seven days and ignores unknown files', () => {
  const expired = resolveExpiredLogFilenames([
    'app-2026-04-14.log',
    'app-2026-04-13.log',
    'app-2026-04-08.log',
    'app-2026-04-07.log',
    'webhook-2026-04-06.log',
    'app.log',
    'webhook.log',
    'random.txt',
  ], '2026-04-14T12:00:00.000Z', 7)

  assert.deepEqual(expired, [
    'app-2026-04-07.log',
    'webhook-2026-04-06.log',
    'app.log',
    'webhook.log',
  ])
})

test('formatLogTimestamp renders readable local timestamp with timezone offset', () => {
  const rendered = formatLogTimestamp('2026-04-14T10:36:24.974Z')
  assert.match(rendered, /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3} [+-]\d{2}:\d{2}$/)
})

test('formatLogEntry prints readable one-line output for flat details', () => {
  const text = formatLogEntry({
    time: '2026-04-14T10:36:24.974Z',
    level: 'info',
    scope: '[http/access]',
    message: 'request completed',
    pid: 4671,
    detail: {
      requestId: 'req-123',
      method: 'GET',
      statusCode: 401,
    },
  }, { color: false })

  assert.match(text, /INFO\s+\[http\/access\] request completed/)
  assert.match(text, /pid=4671/)
  assert.match(text, /requestId=req-123/)
  assert.match(text, /method=GET/)
  assert.match(text, /statusCode=401/)
  assert.doesNotMatch(text, /^\{/)
})

test('formatLogEntry prints nested detail blocks without ansi colors in file mode', () => {
  const text = formatLogEntry({
    time: '2026-04-14T10:36:24.974Z',
    level: 'warn',
    scope: '[admin/auth]',
    message: '后台鉴权失败',
    pid: 4671,
    detail: {
      statusCode: 401,
      errorCode: 'admin_auth_required',
      error: {
        message: '未登录或登录已失效',
        stack: 'Error: test',
      },
    },
  }, { color: false })

  assert.match(text, /WARN\s+\[admin\/auth\] 后台鉴权失败/)
  assert.match(text, /statusCode=401/)
  assert.match(text, /errorCode=admin_auth_required/)
  assert.match(text, /\n  \{/)
  assert.match(text, /未登录或登录已失效/)
  assert.doesNotMatch(text, /\u001B\[/)
})
