import { readFileSync } from 'node:fs';
import { join } from 'node:path';
import * as yaml from 'js-yaml';

/**
 * compose 日志驱动契约。
 *
 * 【为什么显式声明 json-file】docker 默认就是 json-file(写不写行为一样),但
 * **podman rootless 默认是 journald**。2026-08-04 新服务器实测:
 *   - `docker logs <c>` 只回一行兼容层提示
 *   - `podman logs <c>` 返回 0 行
 *   - 日志进了用户 journal,而普通用户不在 systemd-journal 组 → 读不到
 * 等于线上出问题看不到日志。显式声明让两种运行时行为一致。
 *
 * 【顺带治既有隐患】此前无任何 rotate —— 当前生产 /var/lib/docker/containers 已 1.4 GB
 * 且只增不减。2026-08-01 测试服正是被写满后 Postgres 崩溃重启(pg_wal 写不下)。
 */
const compose = yaml.load(
  readFileSync(join(__dirname, '../../../docker-compose.prod.yml'), 'utf-8'),
) as { services: Record<string, { logging?: { driver?: string; options?: Record<string, string> }; profiles?: string[] }> };

describe('docker-compose.prod.yml 日志驱动', () => {
  const names = Object.keys(compose.services);

  test('⭐ 每个服务都声明了 logging —— 漏一个,那个容器在 podman 上就看不到日志', () => {
    const missing = names.filter((n) => !compose.services[n]!.logging);
    expect(missing).toEqual([]);
  });

  test('驱动是 json-file(不是 podman 默认的 journald)', () => {
    for (const n of names) {
      expect(compose.services[n]!.logging!.driver).toBe('json-file');
    }
  });

  test('⭐ 带 rotate 上限 —— 否则日志只增不减,最终吃满磁盘', () => {
    for (const n of names) {
      const opts = compose.services[n]!.logging!.options ?? {};
      expect(opts['max-size']).toBeTruthy();
      expect(opts['max-file']).toBeTruthy();
    }
  });

  test('pac-asr 仍是 profile 可选服务(默认不启,迁移时无需额外处理)', () => {
    expect(compose.services['pac-asr']!.profiles).toContain('asr');
  });
});

describe('docs OpenAPI server 地址', () => {
  test('⭐ 不硬编码域名 —— 这份 compose 测试服与生产共用,写死会让生产 docs 打到测试服', () => {
    const args = (compose.services['pac-docs'] as { build?: { args?: Record<string, string> } }).build?.args ?? {};
    const v = args['DOCS_API_URL'] ?? '';
    expect(v).toMatch(/^\$\{/);                 // 必须是变量插值
    expect(v).not.toMatch(/jarvismedical|friday\.tech/); // 不得出现任何具体域名
    // 复用 NEXT_PUBLIC_API_BASE_URL:它就是同一个东西,各环境 .env 已有,不会再漂移
    expect(v).toContain('NEXT_PUBLIC_API_BASE_URL');
  });
});
