import { describe, it, expect } from 'vitest'
import { readFileSync } from 'node:fs'
import { resolve } from 'node:path'
import {
  evaluate,
  versionBehindPath,
  TRACKED_DIST_PATHS,
} from '../scripts/check-docs-site-version.mjs'

const REPO_ROOT = resolve(__dirname, '..')

const ok = (path: string, version: string) => ({ path, status: 'ok', sha: 'deadbeef', date: '2026-07-30', version })

describe('evaluate — 三态（2 当 0 用就是假绿，所以必须能区分）', () => {
  it('playground-dist 与当前版本一致 → 0', () => {
    expect(evaluate('1.2.0', [ok('playground-dist', '1.2.0'), ok('react-pilot/dist', '1.2.0')])).toEqual({
      code: 0,
      verdict: 'in-sync',
    })
  })

  it('playground-dist 落后 → 1', () => {
    expect(evaluate('1.2.0', [ok('playground-dist', '1.1.1'), ok('react-pilot/dist', '1.1.0')])).toEqual({
      code: 1,
      verdict: 'behind',
    })
  })

  it('任一路径没核到 → 2（不降级成 0，也不冒充 1）', () => {
    const got = evaluate('1.2.0', [
      ok('playground-dist', '1.2.0'),
      { path: 'react-pilot/dist', status: 'unknown', reason: 'no history' },
    ])
    expect(got).toEqual({ code: 2, verdict: 'unknown' })
  })

  it('playground-dist 本身没核到 → 2（不因为"版本不等"就报 1）', () => {
    const got = evaluate('1.2.0', [{ path: 'playground-dist', status: 'unknown', reason: 'x' }])
    expect(got.code).toBe(2)
  })
})

describe('versionBehindPath — 真仓库', () => {
  it('playground-dist 能从 git 推导出一个 semver 版本 + 短 sha + 日期', () => {
    const r = versionBehindPath('playground-dist')
    expect(r.status).toBe('ok')
    expect(r.version).toMatch(/^\d+\.\d+\.\d+$/)
    expect(r.sha).toMatch(/^[0-9a-f]{8}$/)
    expect(r.date).toMatch(/^\d{4}-\d{2}-\d{2}$/)
  })

  it('不存在的路径 → unknown 而不是抛错 / 不是"一致"', () => {
    const r = versionBehindPath('no-such-dir-6f2a')
    expect(r.status).toBe('unknown')
  })
})

describe('接线', () => {
  it('package.json 有 check:docs-site-version', () => {
    const pkg = JSON.parse(readFileSync(resolve(REPO_ROOT, 'package.json'), 'utf-8'))
    expect(pkg.scripts['check:docs-site-version']).toContain('check-docs-site-version.mjs')
  })

  it('release.mjs 在 tag 推完后跑它（不阻塞发版）', () => {
    const src = readFileSync(resolve(REPO_ROOT, 'scripts/release.mjs'), 'utf-8')
    expect(src).toContain('check:docs-site-version')
    // 必须在 push tag 之后：否则报的是发版前的旧版本差，是噪音
    expect(src.indexOf('check:docs-site-version')).toBeGreaterThan(src.indexOf('git push origin master'))
  })

  it('口径真源单一：RELEASING Step 4 不再写 REQUIRED', () => {
    const md = readFileSync(resolve(REPO_ROOT, 'docs/RELEASING.md'), 'utf-8')
    const step4 = md.slice(md.indexOf('### Step 4'), md.indexOf('## Audit gate policy'))
    const heading = step4.slice(0, step4.indexOf('\n'))
    expect(heading).toContain('owner decision')
    expect(heading).not.toContain('(REQUIRED')
    // 并且明说自己是这条规则的唯一真源，别处只指回来
    expect(step4).toContain('唯一真源')
    expect(step4).toContain('check:docs-site-version')
  })

  it('两条 dist 路径都被测量（react-pilot/dist 也会随 docs 站发出去）', () => {
    expect(TRACKED_DIST_PATHS).toEqual(['playground-dist', 'react-pilot/dist'])
  })
})
