import * as fs from 'node:fs';
import * as os from 'node:os';
import * as path from 'node:path';
import {
  resolveOnlyPatientIds,
  resolveOnlyPatientKeys,
} from '../src/modules/sync/cold-import/clickhouse-source.service';

/**
 * PAC_COHORT_ONLY_PATIENT(定向重摄名单)解析。
 *
 * 背景:污染修复要按名单重摄 3 万个患者,逗号串约 275KB > 环境变量 128KB(MAX_ARG_STRLEN)
 *   上限会 E2BIG,故支持 `@file`(每行一个 id)。
 * ⚠️ 本函数还是"是否定向模式"的判定源 —— cold-import 据它决定**不推进增量游标**
 *   (定向轮只覆盖名单内患者,推进全局水位会把名单外患者的 DW 新写入永久埋掉)。
 */
describe('PAC_COHORT_ONLY_PATIENT 解析', () => {
  const ORIG = process.env.PAC_COHORT_ONLY_PATIENT;
  let tmpFile = '';

  afterEach(() => {
    if (ORIG === undefined) delete process.env.PAC_COHORT_ONLY_PATIENT;
    else process.env.PAC_COHORT_ONLY_PATIENT = ORIG;
    if (tmpFile && fs.existsSync(tmpFile)) fs.unlinkSync(tmpFile);
    tmpFile = '';
  });

  test('未设置 → 空数组(非定向模式,游标照常推进)', () => {
    delete process.env.PAC_COHORT_ONLY_PATIENT;
    expect(resolveOnlyPatientIds()).toEqual([]);
  });

  test('空串 / 纯空白 → 空数组(不误判成定向模式)', () => {
    process.env.PAC_COHORT_ONLY_PATIENT = '   ';
    expect(resolveOnlyPatientIds()).toEqual([]);
  });

  test('单个 id', () => {
    process.env.PAC_COHORT_ONLY_PATIENT = '1855960';
    expect(resolveOnlyPatientIds()).toEqual(['1855960']);
  });

  test('逗号列表 → 去空白、丢空项', () => {
    process.env.PAC_COHORT_ONLY_PATIENT = '1855960, 1855959 ,,1855956,';
    expect(resolveOnlyPatientIds()).toEqual(['1855960', '1855959', '1855956']);
  });

  test('@file → 逐行读(大名单绕开 128KB 环境变量上限)', () => {
    tmpFile = path.join(os.tmpdir(), `pids-${Date.now()}.txt`);
    fs.writeFileSync(tmpFile, '1855960\n1855959\n\n  1855956  \n');
    process.env.PAC_COHORT_ONLY_PATIENT = `@${tmpFile}`;
    expect(resolveOnlyPatientIds()).toEqual(['1855960', '1855959', '1855956']);
  });

  test('@file 三万行量级 → 全部读出(真实修复场景规模)', () => {
    tmpFile = path.join(os.tmpdir(), `pids-big-${Date.now()}.txt`);
    const ids = Array.from({ length: 30626 }, (_, i) => String(1000000 + i));
    fs.writeFileSync(tmpFile, ids.join('\n'));
    process.env.PAC_COHORT_ONLY_PATIENT = `@${tmpFile}`;
    const got = resolveOnlyPatientIds();
    expect(got).toHaveLength(30626);
    expect(got[0]).toBe('1000000');
    expect(got[30625]).toBe('1030625');
  });

  test('@file 文件不存在 → 抛错(不静默退化成全量重摄)', () => {
    process.env.PAC_COHORT_ONLY_PATIENT = '@/no/such/pids.txt';
    expect(() => resolveOnlyPatientIds()).toThrow(/不存在/);
  });

  /**
   * 命名空间维(manifest cohort.tenant_key_column 声明的那一维)。
   *
   * 患者主键只在命名空间内唯一 —— jvs-dw 的 patient_id 261067 在两个品牌下是两个人。
   * 2026-08-01 测试服实测:7 万个纯 id 的定向名单列出 **140,566** 个 cohort key(翻倍),
   * 一半是另一命名空间下的同号患者,白摄一倍数据。
   * ⚠️ 维名不写死("brand" 只是 jvs-dw 填进 tenant_key_column 的值),单命名空间宿主写纯 id。
   */
  describe('命名空间维', () => {
    test('纯 id → 无 tenant(单命名空间宿主,行为与改动前一致)', () => {
      process.env.PAC_COHORT_ONLY_PATIENT = '1855960,1855959';
      expect(resolveOnlyPatientKeys()).toEqual([{ key: '1855960' }, { key: '1855959' }]);
    });

    test('`id|命名空间` → 复合键', () => {
      process.env.PAC_COHORT_ONLY_PATIENT = '261067|瑞尔,261067|瑞泰';
      expect(resolveOnlyPatientKeys()).toEqual([
        { key: '261067', tenant: '瑞尔' },
        { key: '261067', tenant: '瑞泰' },
      ]);
    });

    test('TAB 分隔 → 同义(SQL dump TSV 可直接喂)', () => {
      tmpFile = path.join(os.tmpdir(), `pids-tsv-${Date.now()}.txt`);
      fs.writeFileSync(tmpFile, '261067\t瑞尔\n261068\t瑞泰\n');
      process.env.PAC_COHORT_ONLY_PATIENT = `@${tmpFile}`;
      expect(resolveOnlyPatientKeys()).toEqual([
        { key: '261067', tenant: '瑞尔' },
        { key: '261068', tenant: '瑞泰' },
      ]);
    });

    test('resolveOnlyPatientIds 仍只返回 key —— 旧调用点(是否定向模式的判定)不受影响', () => {
      process.env.PAC_COHORT_ONLY_PATIENT = '261067|瑞尔,261068|瑞泰';
      expect(resolveOnlyPatientIds()).toEqual(['261067', '261068']);
    });
  });
});
