import test from "node:test";
import assert from "node:assert/strict";
import crypto from "node:crypto";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { spawnSync } from "node:child_process";
import { fileURLToPath } from "node:url";

const repoRoot = path.resolve(fileURLToPath(new URL("../..", import.meta.url)));
const scriptPath = path.join(repoRoot, "scripts", "release-zhishu.sh");

function createFixture(manifestVersion = "7.1.0") {
  const fixtureRoot = fs.mkdtempSync(path.join(os.tmpdir(), "zhishu-release-"));
  const extensionDir = path.join(fixtureRoot, "智枢获客系统");
  const releaseDir = path.join(fixtureRoot, "发布包");

  fs.mkdirSync(extensionDir, { recursive: true });
  fs.mkdirSync(releaseDir, { recursive: true });
  fs.writeFileSync(
    path.join(extensionDir, "manifest.json"),
    `${JSON.stringify(
      {
        manifest_version: 3,
        name: "智枢获客系统",
        version: manifestVersion
      },
      null,
      2
    )}\n`
  );

  return fixtureRoot;
}

function computeSha256(filePath) {
  const hash = crypto.createHash("sha256");
  hash.update(fs.readFileSync(filePath));
  return hash.digest("hex");
}

function writeExecutable(filePath, contents) {
  fs.writeFileSync(filePath, contents);
  fs.chmodSync(filePath, 0o755);
}

function createRemoteStubEnvironment(fixtureRoot) {
  const binDir = path.join(fixtureRoot, "fake-bin");
  const remoteRoot = path.join(fixtureRoot, "fake-remote");
  const liveRoot = path.join(remoteRoot, "live-root");
  const repoRoot = path.join(remoteRoot, "repo-root");
  const tmpRoot = path.join(remoteRoot, "tmp");
  const downloadsDir = path.join(liveRoot, "downloads");
  const assetsDir = path.join(liveRoot, "assets");
  const repoDownloadsDir = path.join(repoRoot, "downloads");
  const initialPage = `<!doctype html>
<html>
  <body>
    <p>下载内容包含插件文件夹与安装说明。当前下载文件为《智枢获客系统7.0.zip》。</p>
    <a class="btn primary" href="./downloads/zhishu-lead-system-7.0.zip" download="智枢获客系统7.0.zip">下载安装包</a>
  </body>
</html>
`;

  fs.mkdirSync(binDir, { recursive: true });
  fs.mkdirSync(downloadsDir, { recursive: true });
  fs.mkdirSync(assetsDir, { recursive: true });
  fs.mkdirSync(repoDownloadsDir, { recursive: true });
  fs.mkdirSync(tmpRoot, { recursive: true });
  fs.writeFileSync(path.join(liveRoot, "zhishu-lead-system.html"), initialPage);
  fs.writeFileSync(path.join(repoRoot, "zhishu-lead-system.html"), initialPage);

  writeExecutable(
    path.join(binDir, "scp"),
    `#!/bin/sh
set -eu
src="$1"
dest="$2"
remote_path="\${dest#*:}"
mkdir -p "$TEST_FAKE_REMOTE_ROOT$(dirname "$remote_path")"
cp "$src" "$TEST_FAKE_REMOTE_ROOT$remote_path"
`
  );

  writeExecutable(
    path.join(binDir, "ssh"),
    `#!/bin/sh
set -eu
host="$1"
shift
while [ "$#" -gt 0 ]; do
  if [ "$1" = "--" ]; then
    shift
    break
  fi
  shift
done
remote_tmp="$1"
live_root="$2"
repo_root="$3"
package_label="$4"
skip_compat="$5"
remote_tmp_path="$TEST_FAKE_REMOTE_ROOT$remote_tmp"
live_root_path="$TEST_FAKE_LIVE_ROOT"
repo_root_path="$TEST_FAKE_REPO_ROOT"
downloads="$live_root_path/downloads"
repo_downloads="$repo_root_path/downloads"
asset_alias="$live_root_path/assets/zhishu-lead-system-package.zip"
page="$live_root_path/zhishu-lead-system.html"
repo_page="$repo_root_path/zhishu-lead-system.html"
mkdir -p "$downloads" "$repo_downloads" "$live_root_path/assets"
cp "$remote_tmp_path" "$downloads/zhishu-lead-system-$package_label.zip"
if [ "$skip_compat" = "0" ]; then
  cp "$remote_tmp_path" "$downloads/zhishu-lead-system-7.0.zip"
  cp "$remote_tmp_path" "$downloads/zhishu-lead-system-6.9.zip"
  cp "$remote_tmp_path" "$asset_alias"
fi
export RELEASE_PACKAGE_LABEL="$package_label"
perl -0pi -e '
  my $label = $ENV{RELEASE_PACKAGE_LABEL};
  s/智枢获客系统[0-9.]+\\.zip/"智枢获客系统\${label}.zip"/ge;
  s#\\./downloads/zhishu-lead-system-[0-9.]+\\.zip#"./downloads/zhishu-lead-system-\${label}.zip"#ge;
' "$page"
cp "$page" "$repo_page"
cp "$downloads/zhishu-lead-system-$package_label.zip" "$repo_downloads/zhishu-lead-system-$package_label.zip"
cp "$downloads/zhishu-lead-system-$package_label.zip" "$repo_root_path/智枢获客系统$package_label.zip"
rm -f "$remote_tmp_path"
sha256sum "$downloads/zhishu-lead-system-$package_label.zip"
sha256sum "$repo_downloads/zhishu-lead-system-$package_label.zip"
grep -nE "智枢获客系统[0-9.]+\\.zip|downloads/zhishu-lead-system-[0-9.]+\\.zip" "$page"
`
  );

  writeExecutable(
    path.join(binDir, "curl"),
    `#!/bin/sh
set -eu
output=""
url=""
while [ "$#" -gt 0 ]; do
  case "$1" in
    -o)
      output="$2"
      shift 2
      ;;
    -*)
      shift
      ;;
    *)
      url="$1"
      shift
      ;;
  esac
done
case "$url" in
  *downloads/*)
    src="$TEST_FAKE_LIVE_ROOT/downloads/$(basename "$url")"
    if [ -n "$output" ]; then
      cp "$src" "$output"
    else
      cat "$src"
    fi
    ;;
  *)
    cat "$TEST_FAKE_LIVE_ROOT/zhishu-lead-system.html"
    ;;
esac
`
  );

  return {
    binDir,
    liveRoot,
    repoRoot,
    remoteRoot
  };
}

function runScript(args, options = {}) {
  return spawnSync("/bin/bash", [scriptPath, ...args], {
    encoding: "utf8",
    ...options
  });
}

test("release script prints supported modes in help output", () => {
  const result = runScript(["--help"]);

  assert.equal(result.status, 0, result.stderr);
  assert.match(result.stdout, /package-only/);
  assert.match(result.stdout, /deploy/);
  assert.match(result.stdout, /--version/);
});

test("package-only dry run reports the expected archive path", () => {
  const fixtureRoot = createFixture();
  const result = runScript(["package-only", "--project-dir", fixtureRoot, "--version", "7.1.0", "--dry-run"]);

  assert.equal(result.status, 0, result.stderr);
  assert.match(result.stdout, /智枢获客系统7\.1\.zip/);
  assert.match(result.stdout, /manifest version: 7\.1\.0/);
});

test("deploy dry run reports the live web root and host alias", () => {
  const fixtureRoot = createFixture();
  const result = runScript(["deploy", "--project-dir", fixtureRoot, "--version", "7.1.0", "--dry-run"]);

  assert.equal(result.status, 0, result.stderr);
  assert.match(result.stdout, /ecs-agentcore/);
  assert.match(result.stdout, /\/usr\/share\/nginx\/html/);
  assert.match(result.stdout, /\/root\/agentcore-os-site/);
  assert.match(result.stdout, /zhishu-lead-system-7\.1\.zip/);
});

test("deploy appends a release history entry after a successful publish", () => {
  const fixtureRoot = createFixture();
  const remote = createRemoteStubEnvironment(fixtureRoot);
  const result = runScript(["deploy", "--project-dir", fixtureRoot, "--version", "7.1.0"], {
    env: {
      ...process.env,
      PATH: `${remote.binDir}:${process.env.PATH}`,
      TEST_FAKE_REMOTE_ROOT: remote.remoteRoot,
      TEST_FAKE_LIVE_ROOT: remote.liveRoot,
      TEST_FAKE_REPO_ROOT: remote.repoRoot
    }
  });

  const archivePath = path.join(fixtureRoot, "发布包", "智枢获客系统7.1.zip");
  const logPath = path.join(fixtureRoot, "RELEASE_HISTORY.md");
  const archiveSha = computeSha256(archivePath);
  const logContents = fs.readFileSync(logPath, "utf8");
  const livePage = fs.readFileSync(path.join(remote.liveRoot, "zhishu-lead-system.html"), "utf8");

  assert.equal(result.status, 0, result.stderr);
  assert.match(logContents, /7\.1\.0/);
  assert.match(logContents, /智枢获客系统7\.1\.zip/);
  assert.match(logContents, new RegExp(archiveSha));
  assert.match(logContents, /https:\/\/www\.agentcoreos\.com\/downloads\/zhishu-lead-system-7\.1\.zip/);
  assert.match(logContents, /\/usr\/share\/nginx\/html/);
  assert.match(logContents, /\/root\/agentcore-os-site/);
  assert.match(livePage, /智枢获客系统7\.1\.zip/);
});
