#!/usr/bin/env node

import { spawnSync } from 'node:child_process'
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs'
import path from 'node:path'
import process from 'node:process'

const root = path.resolve(import.meta.dirname, '..')
const releaseId = 'cache-contract-test'
const yarn = process.platform === 'win32' ? 'yarn.cmd' : 'yarn'

function run(args) {
  const result = spawnSync(yarn, args, {
    cwd: root,
    env: { ...process.env, VITE_RELEASE_ID: releaseId },
    stdio: 'inherit',
  })
  if (result.status !== 0) process.exit(result.status ?? 1)
}

function files(directory, suffix) {
  return readdirSync(directory, { withFileTypes: true }).flatMap(entry => {
    const current = path.join(directory, entry.name)
    if (entry.isDirectory()) return files(current, suffix)
    return entry.name.endsWith(suffix) ? [current] : []
  })
}

function requireText(file, values) {
  const content = readFileSync(file, 'utf8')
  for (const value of values) {
    if (!content.includes(value)) {
      throw new Error(`${path.relative(root, file)} 缺少缓存契约：${value}`)
    }
  }
}

function verifyBuild(output, publicPrefix) {
  const assetDirectory = path.join(output, 'releases', releaseId, 'assets')
  if (!existsSync(assetDirectory) || !statSync(assetDirectory).isDirectory()) {
    throw new Error(`${path.relative(root, output)} 未生成版本化 assets 目录`)
  }
  const html = files(output, '.html').map(file => readFileSync(file, 'utf8')).join('\n')
  const expected = `${publicPrefix}releases/${releaseId}/assets/`
  if (!html.includes(expected)) {
    throw new Error(`${path.relative(root, output)} 的 HTML 未引用 ${expected}`)
  }
}

run(['workspace', 'tenant-platform', 'build'])
run(['workspace', 'ops-platform', 'build'])
run(['workspace', '@xuqm/docs-site', 'build'])

verifyBuild(path.join(root, 'tenant-platform', 'dist'), '/')
verifyBuild(path.join(root, 'ops-platform', 'dist'), '/')
verifyBuild(path.join(root, 'docs-site', 'docs', '.vitepress', 'dist'), '/docs/')

for (const nginx of ['nginx/tenant.conf', 'nginx/ops.conf']) {
  requireText(path.join(root, nginx), [
    'no-cache, no-store, must-revalidate',
    'public, max-age=31536000, immutable',
    'try_files $uri =404',
  ])
}
for (const dockerfile of ['Dockerfile.tenant', 'Dockerfile.ops']) {
  requireText(path.join(root, dockerfile), [
    'ARG PREVIOUS_IMAGE=',
    '/etc/xuqm_asset_layout_v2',
    'COPY --from=previous',
    'VITE_RELEASE_ID=${SERVICE_VERSION}',
  ])
}

console.log('Web 缓存与上一版本资源保留契约验证通过')
