/**
 * preflight.ts — TUI 부트 전 자기 검사
 *
 * Worker를 스폰하기 전에 빠르게 실패할 수 있는 조건들을 검사:
 * 1. JSX 트랜스폼 — SolidJS/OpenTUI 런타임 로드 가능한지
 * 2. Bun 버전 — 최소 버전 충족
 * 3. 필수 의존성 — node_modules에 핵심 패키지 있는지
 * 4. 디스크 공간 — 임시 파일/스냅샷 저장 가능한지
 * 5. 포트 가용성 — 서버 바인딩 가능한지
 * 6. 이전 크래시 로그 — 마지막 실행에서 크래시했는지
 *
 * 모든 체크는 동기적이고 100ms 이내 완료.
 */

import * as Log from "@saeeol/core/util/log"
import { Filesystem } from "@/util/filesystem"
import path from "path"
import fs from "fs"

export interface PreflightResult {
  severity: "error" | "warning"
  message: string
}

export function preflight(): PreflightResult[] {
  const results: PreflightResult[] = []

  // 1. JSX 런타임 — SolidJS/OpenTUI 로드 가능한지
  try {
    require.resolve("@opentui/solid")
  } catch {
    // Bun 소스 모드에서는 require.resolve가 안 될 수 있음
    // 대신 실제 import 테스트
    try {
      // jsxImportSource가 제대로 설정되었는지 간접 확인
      // bun 실행 시 --jsx-import-source가 전달되었는지
      const tsconfigPath = path.resolve(import.meta.dir, "../../../../tsconfig.json")
      if (fs.existsSync(tsconfigPath)) {
        const tsconfig = JSON.parse(fs.readFileSync(tsconfigPath, "utf8"))
        const jsxSource = tsconfig.compilerOptions?.jsxImportSource
        if (jsxSource && jsxSource !== "@opentui/solid") {
          results.push({
            severity: "error",
            message: `jsxImportSource is "${jsxSource}", expected "@opentui/solid" — run with --jsx-import-source=@opentui/solid`,
          })
        }
      }
    } catch {
      // tsconfig 읽기 실패 — 무시 (빌드된 바이너리면 tsconfig 없음)
    }
  }

  // 2. Bun 버전 체크 (소스 모드에서만)
  if (typeof Bun !== "undefined") {
    const version = Bun.version
    const [major, minor] = version.split(".").map(Number)
    if (major < 1 || (major === 1 && minor < 1)) {
      results.push({
        severity: "warning",
        message: `Bun ${version} detected — TUI requires Bun 1.1.0+ for SolidJS JSX support`,
      })
    }
  }

  // 3. 필수 패키지 존재 확인
  const rootDir = path.resolve(import.meta.dir, "../../../../")
  const requiredPackages = ["@opentui/core", "@opentui/solid"]
  for (const pkg of requiredPackages) {
    const pkgPath = path.join(rootDir, "node_modules", pkg, "package.json")
    if (!fs.existsSync(pkgPath)) {
      results.push({
        severity: "error",
        message: `Missing dependency: ${pkg} — run your package manager install`,
      })
    }
  }

  // 4. 디스크 공간 — 임시 디렉토리 쓰기 가능한지
  const tmpDir = path.resolve(import.meta.dir, "../.tui-tmp")
  try {
    fs.mkdirSync(tmpDir, { recursive: true })
    const testFile = path.join(tmpDir, ".preflight-write-test")
    fs.writeFileSync(testFile, "ok")
    fs.unlinkSync(testFile)
  } catch (err) {
    results.push({
      severity: "error",
      message: `Cannot write to TUI temp directory: ${(err as Error).message}`,
    })
  }

  // 5. 이전 크래시 로그 표시
  const crashLog = path.resolve(import.meta.dir, "../.tui-crash.log")
  if (fs.existsSync(crashLog)) {
    try {
      const stat = fs.statSync(crashLog)
      const ageMs = Date.now() - stat.mtimeMs
      // 최근 10분 이내 크래시면 표시
      if (ageMs < 10 * 60 * 1000) {
        const content = fs.readFileSync(crashLog, "utf8").trim().slice(0, 200)
        results.push({
          severity: "warning",
          message: `Previous TUI crash detected (${Math.round(ageMs / 1000)}s ago): ${content}`,
        })
      }
      // 오래된 크래시 로그는 자동 삭제
      fs.unlinkSync(crashLog)
    } catch {
      // 읽기 실패면 무시
    }
  }

  // 6. Worker 파일 존재 확인
  // target()이 이미 체크하므로 여기서는 스킵

  // 7. 터미널 capabilities — TUI가 필요한 기능이 있는지
  if (process.env.TERM === "dumb") {
    results.push({
      severity: "warning",
      message: `TERM=dumb — TUI may not render correctly. Set TERM=xterm-256color`,
    })
  }

  return results
}

/**
 * 크래시 로그 기록 — TUI 종료 시 에러가 있으면 호출
 */
export function writeCrashLog(error: unknown): void {
  try {
    const crashLog = path.resolve(import.meta.dir, "../.tui-crash.log")
    const message = error instanceof Error ? `${error.name}: ${error.message}\n${error.stack?.slice(0, 500)}` : String(error)
    fs.writeFileSync(crashLog, message)
  } catch {
    // 크래시 로그 자체가 실패하면 무시
  }
}
