// SPEC: PJ2026-01060307 控制面模块化 draft-2026-06-25-p0. source module for scripts/src/hwlab-g14.ts.

// Moved mechanically from scripts/src/hwlab-g14.ts:1205-1308 for #903.

import { chmodSync, existsSync, mkdirSync, readFileSync, rmSync, statSync, writeFileSync } from "node:fs";
import { dirname, join } from "node:path";
import { createHash, randomBytes } from "node:crypto";
import { repoRoot, rootPath, type Config } from "../config";
import { runCommand } from "../command";
import { cancelJob, listJobs, readJob, startJob } from "../jobs";
import { hwlabRequiredNoProxyEntries, hwlabRuntimeLaneConfigPath, hwlabRuntimeLaneIds, hwlabRuntimeLaneSpec, isHwlabRuntimeLane, type HwlabRuntimeLane, type HwlabRuntimeLaneSpec } from "../hwlab-node-lanes";

import type { CommandJsonResult } from "./types";
import { g14HostScript } from "./images";
import { statusText } from "./pr-monitor";
import { commandJson, isCommandSuccess, nested, shellQuote, shortSha } from "./remote";
import { V02_GIT_URL, V02_LANE_SPEC } from "./types";

export function runtimeLaneCicdRepoEnsureScript(spec: HwlabRuntimeLaneSpec): string {
  return [
    `cicd_repo=${shellQuote(spec.cicdRepo)}`,
    `cicd_url=${shellQuote(spec.gitUrl)}`,
    `cicd_branch=${shellQuote(spec.sourceBranch)}`,
    `cicd_repo_lock=${shellQuote(spec.cicdRepoLock)}`,
    "cicd_repo_ensure_fetch() {",
    "  mkdir -p \"$(dirname \"$cicd_repo\")\" || return $?",
    "  if [ -d \"$cicd_repo/objects\" ] && [ -f \"$cicd_repo/HEAD\" ]; then",
    "    :",
    "  elif [ -e \"$cicd_repo\" ]; then",
    `    echo "${spec.version} CI/CD repo path exists but is not a bare git repo: $cicd_repo" >&2`,
    "    return 41",
    "  else",
    "    git clone --bare \"$cicd_url\" \"$cicd_repo\" || return $?",
    "  fi",
    "  git --git-dir=\"$cicd_repo\" remote set-url origin \"$cicd_url\" 2>/dev/null || git --git-dir=\"$cicd_repo\" remote add origin \"$cicd_url\" || return $?",
    "  git --git-dir=\"$cicd_repo\" config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*' || return $?",
    "  git --git-dir=\"$cicd_repo\" fetch origin \"+refs/heads/$cicd_branch:refs/remotes/origin/$cicd_branch\" --prune || return $?",
    "}",
    "cicd_repo_lock_mode=none",
    "if command -v flock >/dev/null 2>&1; then",
    "  exec 9>\"$cicd_repo_lock\"",
    `  flock -w 120 9 || { echo "timed out waiting for ${spec.version} CI/CD repo lock: $cicd_repo_lock" >&2; exit 42; }`,
    "  cicd_repo_lock_mode=flock",
    "else",
    "  cicd_repo_lock_dir=\"$cicd_repo_lock.d\"",
    "  cicd_repo_lock_attempt=0",
    "  while ! mkdir \"$cicd_repo_lock_dir\" 2>/dev/null; do",
    "    cicd_repo_lock_attempt=$((cicd_repo_lock_attempt + 1))",
    `    if [ "$cicd_repo_lock_attempt" -ge 120 ]; then echo "timed out waiting for ${spec.version} CI/CD repo lock: $cicd_repo_lock_dir" >&2; exit 42; fi`,
    "    sleep 1",
    "  done",
    "  cicd_repo_lock_mode=dir",
    "fi",
    "cicd_repo_status=0",
    "cicd_repo_ensure_fetch || cicd_repo_status=$?",
    "if [ \"$cicd_repo_lock_mode\" = flock ]; then flock -u 9 >/dev/null 2>&1 || true; fi",
    "if [ \"$cicd_repo_lock_mode\" = dir ]; then rmdir \"$cicd_repo_lock_dir\" >/dev/null 2>&1 || true; fi",
    `if [ "$cicd_repo_status" -ne 0 ]; then echo "${spec.version} CI/CD repo refresh failed status=$cicd_repo_status repo=$cicd_repo" >&2; exit "$cicd_repo_status"; fi`,
  ].join("\n");
}

export function v02CicdRepoEnsureScript(): string {
  return runtimeLaneCicdRepoEnsureScript(V02_LANE_SPEC);
}

export function resolveV02Head(): { sourceCommit: string | null; result: CommandJsonResult } {
  const result = g14HostScript([
    "set -eu",
    v02CicdRepoEnsureScript(),
    "git --git-dir=\"$cicd_repo\" rev-parse refs/remotes/origin/v0.2",
  ].join("\n"), 180_000);
  if (!isCommandSuccess(result)) return { sourceCommit: null, result };
  const output = String(nested(result.parsed, ["data", "stdout"]) ?? result.stdout).trim();
  const match = /[0-9a-f]{40}/iu.exec(output);
  return { sourceCommit: match?.[0] ?? null, result };
}

export function getV02Head(): string | null {
  return resolveV02Head().sourceCommit;
}

export function resolveV02LatestRemoteHead(): { sourceCommit: string | null; result: CommandJsonResult } {
  const result = commandJson(["git", "ls-remote", V02_GIT_URL, "refs/heads/v0.2"], 30_000);
  if (!isCommandSuccess(result)) return { sourceCommit: null, result };
  const output = statusText(result);
  const match = /^[0-9a-f]{40}/imu.exec(output);
  return { sourceCommit: match?.[0] ?? null, result };
}

export function resolveRuntimeLaneHead(spec: HwlabRuntimeLaneSpec): { sourceCommit: string | null; result: CommandJsonResult } {
  const result = g14HostScript([
    "set -eu",
    runtimeLaneCicdRepoEnsureScript(spec),
    `git --git-dir="$cicd_repo" rev-parse refs/remotes/origin/${spec.sourceBranch}`,
  ].join("\n"), 180_000);
  if (!isCommandSuccess(result)) return { sourceCommit: null, result };
  const output = String(nested(result.parsed, ["data", "stdout"]) ?? result.stdout).trim();
  const match = /[0-9a-f]{40}/iu.exec(output);
  return { sourceCommit: match?.[0] ?? null, result };
}

export function resolveRuntimeLaneLatestRemoteHead(spec: HwlabRuntimeLaneSpec): { sourceCommit: string | null; result: CommandJsonResult } {
  const result = commandJson(["git", "ls-remote", spec.gitUrl, `refs/heads/${spec.sourceBranch}`], 30_000);
  if (!isCommandSuccess(result)) return { sourceCommit: null, result };
  const output = statusText(result);
  const match = /^[0-9a-f]{40}/imu.exec(output);
  return { sourceCommit: match?.[0] ?? null, result };
}

export function runtimeLanePipelineRunName(spec: HwlabRuntimeLaneSpec, sourceCommit: string): string {
  return `${spec.pipelineRunPrefix}-${shortSha(sourceCommit)}`;
}

export function runtimeLaneRerunPipelineRunName(spec: HwlabRuntimeLaneSpec, sourceCommit: string, now = new Date()): string {
  const stamp = now.toISOString().replace(/\D/gu, "").slice(0, 14);
  return `${runtimeLanePipelineRunName(spec, sourceCommit)}-r${stamp}`;
}

export function v02PipelineRunName(sourceCommit: string): string {
  return runtimeLanePipelineRunName(V02_LANE_SPEC, sourceCommit);
}
