import test from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import {
  buildPublicUrl,
  buildPublicZonePageUrl,
  buildPublishConstraints,
  buildSandboxSessionConstraints,
  ensureUserPublishLayout,
  isPathInsidePublishDir,
  migrateUserPublishDir,
  PUBLISH_ROOT_DIR,
  PUBLIC_ZONE_DIR,
  resolveLegacyPublishDir,
} from './user-publish.mjs';
import { syncSkillsToWorkspace } from './skills-registry.mjs';
import { listPlatformSkillCatalog } from './skills-registry.mjs';

const USER_ID = 'a6fb1e97-2b0f-447b-b138-4561d8e5c53e';

test('publish dir and public url use stable user id', () => {
  const platformRoot = path.dirname(fileURLToPath(import.meta.url));
  const h5Root = fs.mkdtempSync(path.join(os.tmpdir(), 'h5-'));
  const layout = ensureUserPublishLayout({
    h5Root,
    publicBaseUrl: 'https://m.tkmind.cn',
    user: { id: USER_ID, username: 'john' },
  });
  assert.equal(layout.slug, USER_ID);
  assert.equal(layout.username, 'john');
  assert.ok(layout.publishDir.endsWith(`${path.sep}${PUBLISH_ROOT_DIR}${path.sep}${USER_ID}`));
  assert.equal(layout.publicUrl, `https://m.tkmind.cn/${PUBLISH_ROOT_DIR}/${USER_ID}/`);
  assert.equal(
    buildPublicUrl('https://m.tkmind.cn', USER_ID, 'report.html'),
    `https://m.tkmind.cn/${PUBLISH_ROOT_DIR}/${USER_ID}/report.html`,
  );
  assert.equal(
    buildPublicZonePageUrl('https://m.tkmind.cn', USER_ID, 'report.html'),
    `https://m.tkmind.cn/${PUBLISH_ROOT_DIR}/${USER_ID}/${PUBLIC_ZONE_DIR}/report.html`,
  );
  assert.equal(
    buildPublicZonePageUrl('https://m.tkmind.cn', USER_ID, `${PUBLIC_ZONE_DIR}/report.html`),
    `https://m.tkmind.cn/${PUBLISH_ROOT_DIR}/${USER_ID}/${PUBLIC_ZONE_DIR}/report.html`,
  );
  const catalog = listPlatformSkillCatalog(platformRoot);
  syncSkillsToWorkspace({
    h5Root: platformRoot,
    publishDir: layout.publishDir,
    skillMap: { 'static-page-publish': true },
    catalog,
    user: { id: USER_ID, username: 'john' },
    publicBaseUrl: 'https://m.tkmind.cn',
  });
  const skillPath = path.join(layout.publishDir, '.agents', 'skills', 'static-page-publish', 'SKILL.md');
  assert.ok(fs.existsSync(skillPath));
  const skillText = fs.readFileSync(skillPath, 'utf8');
  assert.match(skillText, new RegExp(`g2\\.tkmind\\.cn/${PUBLISH_ROOT_DIR}/${USER_ID}/${PUBLIC_ZONE_DIR}/`));
  assert.match(skillText, /public\/report\.html/);
  assert.match(skillText, /\[.*\]\(.*\)/);
  assert.match(skillText, /mindspace-cover/);
  assert.match(skillText, /\.thumbnail\.svg/);
});

test('migrateUserPublishDir merges legacy username directory', () => {
  const h5Root = fs.mkdtempSync(path.join(os.tmpdir(), 'h5-'));
  const legacyDir = resolveLegacyPublishDir(h5Root, { username: 'john' });
  fs.mkdirSync(legacyDir, { recursive: true });
  fs.writeFileSync(path.join(legacyDir, 'legacy.html'), '<html></html>');
  const layout = ensureUserPublishLayout({
    h5Root,
    publicBaseUrl: 'https://m.tkmind.cn',
    user: { id: USER_ID, username: 'john' },
  });
  assert.ok(fs.existsSync(path.join(layout.publishDir, 'legacy.html')));
});

test('buildPublishConstraints scopes default search to user workspace', () => {
  const publishDir = `/var/h5/${PUBLISH_ROOT_DIR}/${USER_ID}`;
  const constraints = buildPublishConstraints({
    slug: USER_ID,
    username: 'john',
    displayName: 'John',
    publicBaseUrl: 'https://m.tkmind.cn',
    publishDir,
  });
  assert.match(constraints, /唯一文件根目录/);
  assert.match(constraints, /禁止把用户叫作 TKMind/);
  assert.match(constraints, /\*\*John\*\*/);
  assert.doesNotMatch(constraints, /对用户统一称 \*\*TKMind\*\*/);
  assert.match(constraints, /禁止用公网 URL 列目录/);
  assert.match(constraints, /public\/页面\.html/);
  assert.match(constraints, /\/public\//);
});

test('buildSandboxSessionConstraints documents shell and forbids public url browsing', () => {
  const text = buildSandboxSessionConstraints({
    baseConstraints: 'base',
    developerTools: ['write', 'edit', 'shell', 'tree'],
  });
  assert.match(text, /shell 已开启/);
  assert.match(text, /禁止.*curl/);
  assert.match(text, /list_dir 可用/);
  assert.match(text, /public\/xxx\.html/);
  assert.match(text, /\/public\//);
});

test('isPathInsidePublishDir blocks escape', () => {
  const publishDir = `/var/h5/${PUBLISH_ROOT_DIR}/${USER_ID}`;
  assert.equal(isPathInsidePublishDir(publishDir, `/var/h5/${PUBLISH_ROOT_DIR}/${USER_ID}/report.html`), true);
  assert.equal(isPathInsidePublishDir(publishDir, `/var/h5/${PUBLISH_ROOT_DIR}/other-id/x.html`), false);
});
