
import { readFile } from "node:fs/promises";
import path from "node:path";
import { fileURLToPath } from "node:url";

import { buildMetadataFromEnv, imageTagFromReference, normalizeIsoTimestamp } from "../build-metadata.mjs";
import { ENVIRONMENT_DEV, SERVICE_IDS } from "../protocol/index.mjs";
import { CLOUD_API_SERVICE_ID } from "../audit/index.mjs";
import { parseStructuredConfig } from "../../scripts/src/structured-config.mjs";

const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
const LIVE_BUILD_TIMEOUT_MS = 900;
const LIVE_BUILD_DEPLOY_MANIFEST_PATH = "deploy/deploy.yaml";
const LIVE_BUILD_SERVICE_DEFAULTS = Object.freeze({
  "hwlab-cloud-api": Object.freeze({ urlEnv: null, defaultUrl: "http://127.0.0.1:6667" }),
  "hwlab-cloud-web": Object.freeze({ urlEnv: "HWLAB_CLOUD_WEB_SERVICE_URL" }),
  "hwlab-gateway": Object.freeze({ urlEnv: "HWLAB_GATEWAY_URL" }),
  "hwlab-edge-proxy": Object.freeze({ urlEnv: "HWLAB_EDGE_PROXY_URL", healthPath: "/health" }),
  "hwlab-agent-skills": Object.freeze({ urlEnv: "HWLAB_AGENT_SKILLS_URL" })
});
const LIVE_BUILD_EXTERNAL_COMPONENTS = Object.freeze([
  Object.freeze({
    serviceId: "hwlab-frpc",
    serviceName: "hwlab-frpc",
    kind: "external",
    externalImage: true,
    defaultImage: "127.0.0.1:5000/hwlab/frpc:v0.68.1",
    externalReason: "外部镜像或非 HWLAB 构建产物"
  })
]);
function defaultRuntimeEnvironment(env = process.env) {
  const value = env.HWLAB_GITOPS_PROFILE || env.HWLAB_ENVIRONMENT || ENVIRONMENT_DEV;
  return typeof value === "string" && value.trim() ? value.trim() : ENVIRONMENT_DEV;
}

function liveBuildProfile(env = process.env) {
  return defaultRuntimeEnvironment(env);
}

export async function buildLiveBuildsPayload(options = {}, dependencies = {}) {
  const env = options.env ?? process.env;
  const metadata = await observeLiveBuildPhase(options, "metadata", () => loadLiveBuildMetadata(options, env));
  const inventory = await observeLiveBuildPhase(options, "inventory", async () => liveBuildServiceInventory(metadata, env), {
    "hwlab.live_builds.deploy_manifest_status": metadata.deployManifest?.status ?? null,
    "hwlab.live_builds.artifact_catalog_status": metadata.artifactCatalog?.status ?? null
  });
  const services = await Promise.all(
    inventory.map((service) => observeLiveBuildPhase(
      options,
      "service_health",
      () => observeLiveBuildService(service, { ...options, env, buildHealthPayload: dependencies.buildHealthPayload }),
      {
        "hwlab.live_builds.service_id": service.serviceId,
        "hwlab.live_builds.service_kind": service.kind,
        "hwlab.live_builds.external": Boolean(service.externalImage)
      }
    ))
  );
  const hwlabServices = services.filter((service) => service.kind === "hwlab");
  const latest = [...hwlabServices]
    .filter((service) => service.build.createdAt)
    .sort((left, right) => Date.parse(right.build.createdAt) - Date.parse(left.build.createdAt))[0] ?? null;

  return {
    serviceId: CLOUD_API_SERVICE_ID,
    environment: (dependencies.runtimeEnvironment ?? defaultRuntimeEnvironment)(env),
    status: "ok",
    contractVersion: "live-builds-v1",
    observedAt: new Date().toISOString(),
    source: {
      kind: "live-health+deploy-artifact-catalog",
      route: "/v1/live-builds",
      healthPath: "/health/live",
      metadataPaths: metadata.paths,
      desiredStateSource: metadata.deployManifest.status === "ok" ? metadata.paths.deployManifest : "unavailable",
      artifactCatalogSource: metadata.artifactCatalog.status === "ok" ? metadata.paths.artifactCatalog : "unavailable",
      note: "Each row prefers current live service health build metadata and falls back only to deploy/artifact catalog metadata when the live tag/revision matches; observedAt is not used as build time."
    },
    latest,
    counts: {
      total: services.length,
      hwlab: hwlabServices.length,
      withBuildTime: hwlabServices.filter((service) => Boolean(service.build.createdAt)).length,
      unavailable: hwlabServices.filter((service) => service.build.createdAt === null).length,
      external: services.filter((service) => service.kind === "external").length
    },
    services
  };
}

async function observeLiveBuildPhase(options, phase, operation, attributes = {}) {
  if (typeof options.observeLiveBuildPhase === "function") {
    return options.observeLiveBuildPhase(phase, operation, attributes);
  }
  return operation();
}

async function observeLiveBuildService(service, options) {
  if (service.externalImage) {
    return externalLiveBuildRecord(service, {
      healthUrl: null,
      httpStatus: null,
      imageReference: service.defaultImage ?? "unknown",
      reason: "外部镜像或非 HWLAB 构建产物"
    });
  }

  const metadataRecords = liveBuildRecordsFromMetadata(service);
  const metadataRecord = metadataRecords[0] ?? null;
  if (service.serviceId === CLOUD_API_SERVICE_ID) {
    const health = await options.buildHealthPayload({ ...options, healthMode: "live" });
    return liveBuildRecordFromHealth(service, {
      ok: true,
      status: 200,
      url: "/health/live",
      payload: health
    }, metadataRecords);
  }

  const baseUrl = String(options.env?.[service.urlEnv] || service.defaultUrl || "").replace(/\/+$/u, "");
  if (!baseUrl) {
    return metadataRecord
      ? metadataRecordWithHealthGap(metadataRecord, {
        service,
        healthUrl: null,
        httpStatus: null,
        reason: `${service.serviceId} 没有配置 live health URL`
      })
      : unavailableLiveBuildRecord(service, {
        reasonCode: "service_url_unavailable",
        reason: `${service.serviceId} 没有配置 live health URL`
      });
  }

  const healthPath = service.healthPath ?? "/health/live";
  return liveBuildRecordFromHealth(
    service,
    await fetchServiceHealth(`${baseUrl}${healthPath}`, options.fetchImpl ?? fetch),
    metadataRecords
  );
}

async function fetchServiceHealth(url, fetchImpl) {
  const controller = new AbortController();
  const timeout = setTimeout(() => controller.abort(), LIVE_BUILD_TIMEOUT_MS);
  try {
    const response = await fetchImpl(url, {
      headers: { Accept: "application/json" },
      signal: controller.signal
    });
    const text = await response.text();
    let payload = null;
    try {
      payload = text ? JSON.parse(text) : null;
    } catch {
      return {
        ok: false,
        status: response.status,
        url,
        reasonCode: "invalid_json",
        reason: `${url} returned non-JSON health payload`
      };
    }
    return {
      ok: response.ok,
      status: response.status,
      url,
      payload,
      reasonCode: response.ok ? null : "http_error",
      reason: response.ok ? null : `${url} returned HTTP ${response.status}`
    };
  } catch (error) {
    const timedOut = error?.name === "AbortError";
    return {
      ok: false,
      status: null,
      url,
      reasonCode: timedOut ? "timeout" : "request_failed",
      reason: timedOut ? `${url} timed out after ${LIVE_BUILD_TIMEOUT_MS}ms` : error.message
    };
  } finally {
    clearTimeout(timeout);
  }
}

function liveBuildRecordFromHealth(service, result, metadataRecords = []) {
  const candidates = Array.isArray(metadataRecords) ? metadataRecords : [metadataRecords].filter(Boolean);
  const metadataRecord = candidates[0] ?? null;
  if (!result.ok) {
    const reason = healthUnavailableReason(service, result.reason ?? `${service.serviceId} health unavailable`);
    return metadataRecord
      ? metadataRecordWithHealthGap(metadataRecord, {
        service,
        healthUrl: result.url,
        httpStatus: result.status,
        reason
      })
      : unavailableLiveBuildRecord(service, {
        healthUrl: result.url,
        httpStatus: result.status,
        reasonCode: result.reasonCode ?? "health_unavailable",
        reason
      });
  }

  const payload = result.payload ?? {};
  const payloadServiceId = payload.serviceId ?? service.serviceId;
  if (!String(payloadServiceId).startsWith("hwlab-")) {
    return externalLiveBuildRecord(service, {
      healthUrl: result.url,
      httpStatus: result.status,
      imageReference: payload.image?.reference ?? payload.image ?? "unknown",
      imageTag: payload.image?.tag ?? null,
      imageDigest: payload.image?.digest ?? "unknown",
      commitId: payload.commit?.id ?? payload.revision ?? payload.version ?? "unknown",
      commitSource: payload.commit?.source ?? "external-health",
      revision: payload.revision ?? payload.commit?.id ?? payload.version ?? "unknown",
      reason: "外部镜像或非 HWLAB 构建产物"
    });
  }

  const imageReference = payload.image?.reference ?? payload.image ?? "unknown";
  const commitId = payload.commit?.id ?? payload.revision ?? "unknown";
  const liveIdentity = liveBuildIdentityFromHealth({ payload, imageReference, commitId });
  const createdAt = normalizeHealthBuildTime(payload);
  if (createdAt) {
    return liveBuildHealthPayloadRecord(service, result, {
      payload,
      imageReference,
      commitId,
      createdAt,
      metadataSource: payload.build?.metadataSource ?? "health:build.createdAt",
      unavailableReason: null
    });
  }

  const matched = selectMatchingMetadataRecord(liveIdentity, candidates);
  if (matched.record?.build?.createdAt) {
    return mergeLiveHealthOntoMetadataRecord(matched.record, {
      match: matched.match,
      liveIdentity,
      service,
      result,
      payload,
      imageReference,
      commitId
    });
  }

  const mismatch = matched.match ?? liveBuildMetadataMatch(liveIdentity, metadataRecord);
  const unavailableReason = matched.record
    ? "构建时间不可用：当前 live 镜像未提供 buildCreatedAt"
    : metadataRecord
      ? `构建时间不可用：live tag 与 ${controlledMetadataLabel(metadataRecord)} 不匹配`
      : "构建时间不可用：当前 live 镜像未提供 buildCreatedAt";
  return liveBuildHealthPayloadRecord(service, result, {
    payload,
    imageReference,
    commitId,
    createdAt: null,
    metadataSource: matched.record ? "live-health:matched-controlled-metadata-without-build-time" : metadataRecord ? "live-health:controlled-metadata-mismatch" : "live-health:build-created-at-missing",
    unavailableReason,
    metadataMismatch: mismatch,
    unavailableDetail: matched.record
      ? `live tag ${liveIdentity.imageTag} / revision ${liveIdentity.revision} 已匹配 ${controlledMetadataLabel(matched.record)}，但该 metadata 没有 buildCreatedAt（metadata tag ${matched.record.image.tag}，metadata revision ${matched.record.revision}，来源 ${matched.record.build.metadataSource}）`
      : metadataRecord
        ? `未使用可能过期的构建时间：live tag ${liveIdentity.imageTag}，live revision ${liveIdentity.revision}，metadata tag ${metadataRecord.image.tag}，metadata revision ${metadataRecord.revision}，来源 ${metadataRecord.build.metadataSource}`
        : "health payload 缺少 build.createdAt / image.createdAt / buildCreatedAt，deploy/artifact catalog 也没有可匹配的 buildCreatedAt"
  });
}

function liveBuildHealthPayloadRecord(service, result, {
  payload,
  imageReference,
  commitId,
  createdAt,
  metadataSource,
  unavailableReason,
  metadataMismatch = null,
  unavailableDetail = null
}) {
  return {
    serviceId: service.serviceId,
    name: service.serviceName,
    kind: "hwlab",
    status: createdAt ? "ok" : "build_time_unavailable",
    healthUrl: result.url,
    httpStatus: result.status,
    desiredState: desiredStateSummary(service),
    build: {
      createdAt,
      source: payload.build?.source ?? payload.commit?.source ?? "health-payload",
      metadataSource,
      unavailableReason,
      unavailableDetail,
      metadataMismatch
    },
    image: {
      reference: imageReference,
      tag: payload.image?.tag ?? imageTagFromReference(imageReference) ?? "unknown",
      digest: payload.image?.digest ?? "unknown"
    },
    commit: {
      id: commitId,
      source: payload.commit?.source ?? "health-payload"
    },
    runtime: liveBuildRuntimeSummary(service, payload),
    revision: payload.revision ?? commitId
  };
}

function metadataRecordWithHealthGap(metadataRecord, { service, healthUrl, httpStatus, reason }) {
  const metadataTag = metadataRecord.image?.tag ?? "unknown";
  const metadataRevision = metadataRecord.revision ?? metadataRecord.commit?.id ?? "unknown";
  return {
    ...metadataRecord,
    healthUrl,
    httpStatus,
    status: "build_time_unavailable",
    build: {
      ...metadataRecord.build,
      createdAt: null,
      metadataSource: "live-health-unavailable",
      unavailableReason: `构建时间不可用：当前 live health 不可用，无法确认 ${service.serviceId} live tag/revision 是否匹配 deploy/artifact catalog metadata，未使用可能过期的构建时间（metadata tag ${metadataTag}，metadata revision ${metadataRevision}）；${reason}`
    }
  };
}

function mergeLiveHealthOntoMetadataRecord(metadataRecord, { match, liveIdentity, service, result, payload, imageReference, commitId }) {
  return {
    ...metadataRecord,
    serviceId: service.serviceId,
    name: service.serviceName,
    kind: "hwlab",
    status: "ok",
    healthUrl: result.url,
    httpStatus: result.status,
    build: {
      ...metadataRecord.build,
      metadataSource: metadataRecord.build.metadataSource,
      unavailableReason: null,
      liveMetadataMatch: match,
      liveHealthMissingReason: `health payload 缺少 build.createdAt / image.createdAt / buildCreatedAt，已使用与 live tag/revision 匹配的 ${controlledMetadataLabel(metadataRecord)}（live tag ${liveIdentity.imageTag}）`
    },
    image: {
      reference: imageReference !== "unknown" ? imageReference : metadataRecord.image.reference,
      tag: payload.image?.tag ?? imageTagFromReference(imageReference) ?? metadataRecord.image.tag,
      digest: payload.image?.digest ?? metadataRecord.image.digest
    },
    commit: {
      id: commitId !== "unknown" ? commitId : metadataRecord.commit.id,
      source: payload.commit?.source ?? metadataRecord.commit.source
    },
    runtime: liveBuildRuntimeSummary(service, payload),
    revision: payload.revision ?? (commitId !== "unknown" ? commitId : metadataRecord.revision)
  };
}

function liveBuildRuntimeSummary(service, payload = {}) {
  const runtimeSource = payload?.runtimeIdentity ?? payload?.runtime;
  const runtime = runtimeSource && typeof runtimeSource === "object" ? runtimeSource : {};
  const pod = runtime?.pod && typeof runtime.pod === "object" ? runtime.pod : {};
  const podName = firstNonEmpty(
    payload?.podName,
    runtime?.podName,
    pod?.name,
    payload?.health?.podName
  );
  const namespace = firstNonEmpty(
    payload?.namespace,
    runtime?.namespace,
    pod?.namespace,
    service.runtimeNamespace,
    service.deploy?.namespace,
    service.artifact?.namespace
  );
  const container = firstNonEmpty(
    payload?.container,
    payload?.containerName,
    runtime?.container,
    runtime?.containerName,
    pod?.container,
    pod?.containerName,
    defaultRuntimeContainer(service.serviceId)
  );
  const unideskRoute = podName
    ? namespace ? `G14:k3s:${namespace}:pod:${podName}${container ? `:${container}` : ""}` : null
    : null;
  return pruneUndefined({
    pod: pruneUndefined({
      name: podName,
      namespace,
      container,
      nodeName: firstNonEmpty(pod?.nodeName, runtime?.nodeName, payload?.nodeName)
    }),
    unideskRoute
  });
}

function defaultRuntimeContainer(serviceId) {
  if (["hwlab-cloud-api", "hwlab-cloud-web", "hwlab-agent-skills"].includes(serviceId)) return serviceId;
  return "";
}

function firstNonEmpty(...values) {
  for (const value of values) {
    if (value === null || value === undefined) continue;
    const textValue = String(value).trim();
    if (textValue) return textValue;
  }
  return null;
}

function pruneUndefined(value) {
  return Object.fromEntries(Object.entries(value).filter(([, item]) => item !== undefined && item !== null && item !== ""));
}

function liveBuildIdentityFromHealth({ payload, imageReference, commitId }) {
  return {
    imageReference,
    imageTag: payload.image?.tag ?? imageTagFromReference(imageReference) ?? "unknown",
    commitId,
    revision: payload.revision ?? commitId,
    digest: payload.image?.digest ?? "unknown"
  };
}

function selectMatchingMetadataRecord(liveIdentity, metadataRecords) {
  let firstMatched = null;
  for (const record of metadataRecords) {
    const match = liveBuildMetadataMatch(liveIdentity, record);
    if (!match.matched) continue;
    if (record.build?.createdAt) return { record, match };
    firstMatched ??= { record, match };
  }
  if (firstMatched) return firstMatched;
  return {
    record: null,
    match: metadataRecords.length ? liveBuildMetadataMatch(liveIdentity, metadataRecords[0]) : null
  };
}

function liveBuildMetadataMatch(liveIdentity, metadataRecord) {
  if (!metadataRecord) {
    return {
      matched: false,
      matchedValues: [],
      live: liveBuildIdentitySummary(liveIdentity),
      metadata: null
    };
  }
  const liveValues = uniqueStrings([
    liveIdentity.imageTag,
    imageTagFromReference(liveIdentity.imageReference),
    liveIdentity.revision,
    liveIdentity.commitId,
    liveIdentity.digest
  ]).filter((value) => value !== "unknown");
  const metadataValues = uniqueStrings([
    metadataRecord.image?.tag,
    imageTagFromReference(metadataRecord.image?.reference),
    metadataRecord.revision,
    metadataRecord.commit?.id,
    metadataRecord.image?.digest
  ]).filter((value) => value !== "unknown" && value !== "not_published");
  const matchedValues = liveValues.filter((liveValue) =>
    metadataValues.some((metadataValue) => liveBuildIdentityEquivalent(liveValue, metadataValue))
  );
  return {
    matched: matchedValues.length > 0,
    matchedValues,
    live: liveBuildIdentitySummary(liveIdentity),
    metadata: {
      imageTag: metadataRecord.image?.tag ?? "unknown",
      revision: metadataRecord.revision ?? "unknown",
      commitId: metadataRecord.commit?.id ?? "unknown",
      digest: metadataRecord.image?.digest ?? "unknown"
    }
  };
}

function liveBuildIdentitySummary(identity) {
  return {
    imageTag: identity?.imageTag ?? "unknown",
    revision: identity?.revision ?? "unknown",
    commitId: identity?.commitId ?? "unknown",
    digest: identity?.digest ?? "unknown"
  };
}

function liveBuildIdentityEquivalent(left, right) {
  const a = String(left ?? "").trim();
  const b = String(right ?? "").trim();
  if (!a || !b || a === "unknown" || b === "unknown") return false;
  if (a === b) return true;
  if (a.startsWith("sha256:") || b.startsWith("sha256:")) return false;
  return a.length >= 7 && b.length >= 7 && (a.startsWith(b) || b.startsWith(a));
}

function liveBuildRecordsFromMetadata(service) {
  return [
    liveBuildRecordFromMetadataSource(service, "artifact"),
    liveBuildRecordFromMetadataSource(service, "deploy")
  ].filter(Boolean);
}

function liveBuildRecordFromMetadataSource(service, sourceKind) {
  const source = sourceKind === "artifact"
    ? service.artifact
    : service.deploy;
  if (!source) return null;
  const createdAt = normalizeIsoTimestamp(
    sourceKind === "deploy" ? source.env?.HWLAB_BUILD_CREATED_AT : source.buildCreatedAt
  );

  const imageReference = sourceKind === "deploy"
    ? source.env?.HWLAB_IMAGE ?? source.image ?? "unknown"
    : source.image ?? service.deploy?.image ?? "unknown";
  const commitId = sourceKind === "artifact"
    ? source.commitId ?? imageTagFromReference(imageReference) ?? "unknown"
    : source.env?.HWLAB_COMMIT_ID ?? imageTagFromReference(imageReference) ?? "unknown";
  const digest = sourceKind === "deploy"
    ? source.env?.HWLAB_IMAGE_DIGEST ?? "unknown"
    : source.digest ?? "unknown";
  const buildSource = sourceKind === "deploy"
    ? source.env?.HWLAB_BUILD_SOURCE ?? "deploy-desired-state-env"
    : source.buildSource ?? "artifact-catalog-metadata";
  const imageTag = sourceKind === "deploy"
    ? source.env?.HWLAB_IMAGE_TAG ?? imageTagFromReference(imageReference) ?? "unknown"
    : source.imageTag ?? imageTagFromReference(imageReference) ?? "unknown";
  const revision = sourceKind === "deploy"
    ? source.env?.HWLAB_REVISION ?? commitId
    : commitId;
  return {
    serviceId: service.serviceId,
    name: service.serviceName,
    kind: "hwlab",
    status: createdAt ? "ok" : "build_time_unavailable",
    healthUrl: null,
    httpStatus: null,
    desiredState: desiredStateSummary(service),
    build: {
      createdAt,
      source: buildSource,
      metadataSource: artifactMetadataSource(sourceKind),
      unavailableReason: createdAt
        ? null
        : `构建时间不可用：${controlledMetadataLabel({ build: { metadataSource: artifactMetadataSource(sourceKind) } })} 缺少 buildCreatedAt`
    },
    image: {
      reference: imageReference,
      tag: imageTag,
      digest
    },
    commit: {
      id: commitId,
      source: sourceKind === "artifact" ? "artifact-catalog" : "deploy-desired-state"
    },
    revision
  };
}

function desiredStateSummary(service) {
  return {
    namespace: service.runtimeNamespace ?? service.deploy?.namespace ?? service.artifact?.namespace ?? null,
    profile: service.runtimeProfile ?? service.deploy?.profile ?? service.artifact?.profile ?? ENVIRONMENT_DEV,
    replicas: Number.isFinite(Number(service.deploy?.replicas)) ? Number(service.deploy.replicas) : null,
    healthPath: service.healthPath ?? service.deploy?.healthPath ?? service.artifact?.healthPath ?? "/health/live",
    source: service.deploy ? service.metadataPaths?.deployManifest ?? LIVE_BUILD_DEPLOY_MANIFEST_PATH : "service-defaults"
  };
}

function artifactMetadataSource(sourceKind) {
  if (sourceKind === "artifact") return "artifact-catalog:buildCreatedAt";
  return "deploy-env:HWLAB_BUILD_CREATED_AT";
}

function controlledMetadataLabel(record) {
  const source = String(record?.build?.metadataSource ?? "");
  if (source.includes("artifact-catalog")) return "catalog metadata";
  if (source.includes("deploy-env")) return "deploy metadata";
  return "controlled metadata";
}

function unavailableLiveBuildRecord(service, { healthUrl = null, httpStatus = null, reasonCode, reason }) {
  return {
    serviceId: service.serviceId,
    name: service.serviceName,
    kind: "hwlab",
    status: "unavailable",
    healthUrl,
    httpStatus,
    desiredState: desiredStateSummary(service),
    build: {
      createdAt: null,
      metadataSource: "unavailable",
      unavailableReason: `构建时间不可用：${reason}`
    },
    image: {
      reference: "unknown",
      tag: "unknown",
      digest: "unknown"
    },
    commit: {
      id: "unknown",
      source: "unavailable"
    },
    revision: "unknown",
    error: {
      code: reasonCode,
      message: reason
    }
  };
}

function externalLiveBuildRecord(service, {
  healthUrl = null,
  httpStatus = null,
  imageReference = "unknown",
  imageTag = null,
  imageDigest = "unknown",
  commitId = "unknown",
  commitSource = "external-image",
  revision = commitId,
  reason
}) {
  return {
    serviceId: service.serviceId,
    name: service.serviceName,
    kind: "external",
    status: "external",
    healthUrl,
    httpStatus,
    build: {
      createdAt: null,
      metadataSource: "external-image",
      unavailableReason: reason
    },
    image: {
      reference: imageReference,
      tag: imageTag ?? imageTagFromReference(imageReference) ?? "unknown",
      digest: imageDigest
    },
    commit: {
      id: commitId,
      source: commitSource
    },
    revision
  };
}

function healthUnavailableReason(service, reason) {
  if (Number(service.deploy?.replicas) === 0) {
    const namespace = desiredStateSummary(service).namespace;
    return `${service.serviceId} 当前 ${namespace} desired replicas=0，无可读取的常驻 /health/live：${reason}`;
  }
  if (service.activation === "manual") {
    return `${service.serviceId} 是手动激活服务，当前 live health 不可用：${reason}`;
  }
  return reason;
}

function normalizeHealthBuildTime(payload) {
  return normalizeIsoTimestamp(
    payload?.build?.createdAt ??
    payload?.image?.createdAt ??
    payload?.buildCreatedAt ??
    payload?.metadata?.buildCreatedAt ??
    null
  );
}

async function loadLiveBuildMetadata(options = {}, env = process.env) {
  if (options.liveBuildMetadata) return normalizeLiveBuildMetadata(options.liveBuildMetadata, env);
  const root = options.repoRoot ?? process.env.HWLAB_REPO_ROOT ?? repoRoot;
  const deployManifest = await readJsonMetadata(root, LIVE_BUILD_DEPLOY_MANIFEST_PATH);
  const paths = metadataPathsFromDeployManifest(deployManifest.payload, liveBuildProfile(env));
  const artifactCatalog = await readJsonMetadata(root, paths.artifactCatalog);
  return normalizeLiveBuildMetadata({ deployManifest, artifactCatalog }, paths);
}

function normalizeLiveBuildMetadata(metadata, envOrPaths = process.env) {
  const deployManifest = normalizeMetadataFile(metadata.deployManifest);
  const paths = isMetadataPaths(envOrPaths)
    ? envOrPaths
    : metadataPathsFromDeployManifest(deployManifest.payload, liveBuildProfile(envOrPaths));
  return {
    paths,
    deployManifest,
    artifactCatalog: normalizeMetadataFile(metadata.artifactCatalog)
  };
}

function isMetadataPaths(value) {
  return Boolean(value?.deployManifest && value?.artifactCatalog);
}

function metadataPathsFromDeployManifest(deployManifest, profile) {
  const lane = deployLaneForProfile(deployManifest, profile);
  const artifactCatalog = firstNonEmpty(
    lane?.artifactCatalog,
    deployManifest?.artifactCatalog
  );
  return {
    deployManifest: LIVE_BUILD_DEPLOY_MANIFEST_PATH,
    artifactCatalog
  };
}

async function readJsonMetadata(root, relativePath) {
  try {
    const raw = await readFile(path.join(root, relativePath), "utf8");
    const payload = parseStructuredConfig(raw, relativePath);
    return { status: "ok", path: relativePath, payload };
  } catch (error) {
    return {
      status: "unavailable",
      path: relativePath,
      error: error.message,
      payload: null
    };
  }
}

function normalizeMetadataFile(file) {
  if (file?.status === "ok" || file?.status === "unavailable") {
    return {
      status: file.status,
      path: file.path ?? null,
      error: file.error ?? null,
      payload: file.payload ?? null
    };
  }
  return {
    status: file ? "ok" : "unavailable",
    path: null,
    error: null,
    payload: file ?? null
  };
}

function liveBuildServiceInventory(metadata, env = process.env) {
  const profile = liveBuildProfile(env);
  const lane = deployLaneForProfile(metadata.deployManifest.payload, profile);
  const runtimeNamespace = firstNonEmpty(lane?.namespace, metadata.deployManifest.payload?.namespace);
  const deployServices = deployServicesForProfile(metadata.deployManifest.payload, profile, lane, runtimeNamespace);
  const deployByServiceId = new Map(deployServices.map((service) => [service.serviceId, service]));
  const artifactByServiceId = new Map(
    (Array.isArray(metadata.artifactCatalog.payload?.services) ? metadata.artifactCatalog.payload.services : [])
      .map((service) => normalizeServiceRuntimeTarget(service, profile, runtimeNamespace))
      .map((service) => [service.serviceId, service])
  );
  const serviceIds = uniqueStrings([
    ...SERVICE_IDS,
    ...deployServices.map((service) => service.serviceId),
    ...artifactByServiceId.keys()
  ]).filter((serviceId) => String(serviceId).startsWith("hwlab-") && !serviceRemovedForRuntimeProfile(serviceId, lane));

  return [
    ...serviceIds.map((serviceId) => {
      const deploy = deployByServiceId.get(serviceId) ?? null;
      const defaults = LIVE_BUILD_SERVICE_DEFAULTS[serviceId] ?? {};
      const healthPath = deploy?.healthPath ?? defaults.healthPath ?? "/health/live";
      const defaultUrl = serviceId === CLOUD_API_SERVICE_ID
        ? defaults.defaultUrl ?? serviceDefaultUrl(serviceId, runtimeNamespace)
        : serviceDefaultUrl(serviceId, runtimeNamespace);
      return Object.freeze({
        serviceId,
        serviceName: deploy?.name ?? serviceId,
        urlEnv: defaults.urlEnv ?? serviceUrlEnvName(serviceId),
        defaultUrl,
        healthPath,
        activation: deploy?.replicas === 0 ? "zero-replica" : defaults.activation,
        runtimeProfile: profile,
        runtimeNamespace,
        metadataPaths: metadata.paths,
        deploy,
        artifact: artifactByServiceId.get(serviceId) ?? null
      });
    }),
    ...LIVE_BUILD_EXTERNAL_COMPONENTS
  ];
}

function deployLaneForProfile(deployManifest, profile) {
  const lanes = deployManifest?.lanes && typeof deployManifest.lanes === "object" ? deployManifest.lanes : {};
  return lanes[profile] ?? null;
}

function deployServicesForProfile(deployManifest, profile, lane, runtimeNamespace) {
  const baseServices = Array.isArray(deployManifest?.services) ? deployManifest.services : [];
  if (!lane) return baseServices;
  const servicesById = new Map(baseServices.map((service) => [service.serviceId, { ...service, env: { ...(service.env ?? {}) } }]));
  const laneServices = Array.isArray(lane.services) ? lane.services : [];
  for (const service of laneServices) {
    const current = servicesById.get(service.serviceId) ?? { serviceId: service.serviceId };
    servicesById.set(service.serviceId, {
      ...current,
      ...service,
      env: {
        ...(current.env ?? {}),
        ...(service.env ?? {})
      }
    });
  }
  return [...servicesById.values()].map((service) => normalizeServiceRuntimeTarget(service, profile, runtimeNamespace));
}

function normalizeServiceRuntimeTarget(service, profile, runtimeNamespace) {
  if (!service) return service;
  return {
    ...service,
    namespace: runtimeNamespace,
    profile
  };
}

function serviceRemovedForRuntimeProfile(serviceId, lane) {
  const removed = uniqueStrings([
    ...(Array.isArray(lane?.removedServices) ? lane.removedServices : []),
    ...(Array.isArray(lane?.disabledServices) ? lane.disabledServices : []),
    ...(Array.isArray(lane?.omitServices) ? lane.omitServices : [])
  ]);
  return removed.includes(serviceId);
}

function uniqueStrings(values) {
  return [...new Set(values.map((value) => String(value ?? "").trim()).filter(Boolean))];
}

function serviceUrlEnvName(serviceId) {
  return `${serviceId.replace(/^hwlab-/u, "HWLAB_").replace(/-/gu, "_").toUpperCase()}_URL`;
}

function serviceDefaultUrl(serviceId, namespace = null) {
  if (!namespace) return null;
  const port = {
    "hwlab-cloud-api": 6667,
    "hwlab-cloud-web": 8080,
    "hwlab-gateway": 7001,
    "hwlab-edge-proxy": 6667,
    "hwlab-agent-skills": 7430
  }[serviceId] ?? 8080;
  return `http://${serviceId}.${namespace}.svc.cluster.local:${port}`;
}
