import { mkdtempSync, rmSync, statSync, utimesSync, writeFileSync } from 'node:fs'
import os from 'node:os'
import path from 'node:path'
import { afterEach, describe, expect, it } from 'vitest'
import {
  extractInlinePlanMarkdownPathFromToolResult,
  readInlinePlanMarkdownSync,
} from './render-io'

const tempDirs: string[] = []

afterEach(() => {
  while (tempDirs.length > 0) {
    const dir = tempDirs.pop()
    if (dir) {
      try {
        rmSync(dir, { force: true, recursive: true })
      } catch {}
    }
  }
})

describe('readInlinePlanMarkdownSync', () => {
  it('reads markdown files and refreshes cached content after mtime changes', () => {
    const dir = mkdtempSync(path.join(os.tmpdir(), 'render-io-'))
    tempDirs.push(dir)
    const filePath = path.join(dir, 'plan.md')

    writeFileSync(filePath, '# First\n')
    expect(readInlinePlanMarkdownSync(filePath)).toBe('# First\n')
    expect(readInlinePlanMarkdownSync(filePath)).toBe('# First\n')

    writeFileSync(filePath, '# Second\n')
    const stats = statSync(filePath)
    const nextTime = new Date(stats.mtimeMs + 2_000)
    utimesSync(filePath, nextTime, nextTime)

    expect(readInlinePlanMarkdownSync(filePath)).toBe('# Second\n')
  })

  it('rejects invalid paths, missing files, and oversized files', () => {
    const dir = mkdtempSync(path.join(os.tmpdir(), 'render-io-'))
    tempDirs.push(dir)
    const txtPath = path.join(dir, 'plan.txt')
    const mdPath = path.join(dir, 'large.md')

    writeFileSync(txtPath, 'nope')
    writeFileSync(mdPath, 'x'.repeat(256 * 1024 + 1))

    expect(readInlinePlanMarkdownSync('relative.md')).toBeNull()
    expect(readInlinePlanMarkdownSync(txtPath)).toBeNull()
    expect(readInlinePlanMarkdownSync(path.join(dir, 'missing.md'))).toBeNull()
    expect(readInlinePlanMarkdownSync(mdPath)).toBeNull()
  })
})

describe('extractInlinePlanMarkdownPathFromToolResult', () => {
  it('prefers absolute markdown paths from structured content', () => {
    const dir = mkdtempSync(path.join(os.tmpdir(), 'render-io-'))
    tempDirs.push(dir)
    const filePath = path.join(dir, 'plan.md')

    expect(
      extractInlinePlanMarkdownPathFromToolResult({
        output: '',
        structuredContent: { markdown_path: filePath },
      }),
    ).toBe(filePath)
  })
})
