// SPEC: PJ2026-01060505 Workbench Performance draft-2026-06-17-p0.
// Responsibility: Prometheus/observability expression rendering for HWLAB node runtime.
import type { HwlabRuntimeObservabilityRecordingRuleSpec, HwlabRuntimeObservabilitySpec, HwlabRuntimeObservabilityWarningAlertSpec } from "./hwlab-node-lanes";

export function nodeObservabilityRecordingRuleSummaries(observability: HwlabRuntimeObservabilitySpec): Array<Record<string, unknown>> {
  return observability.recordingRules.map((rule) => ({
    ...rule,
    expression: nodeObservabilityRecordingRuleExpression(rule),
    sampleCountExpression: nodeObservabilitySampleCountExpression(rule, rule.matchLabels),
    lowSampleGuardExpression: `${nodeObservabilitySampleCountExpression(rule, rule.matchLabels)} >= ${rule.minSamples}`,
  }));
}

export function nodeObservabilityWarningAlertSummaries(observability: HwlabRuntimeObservabilitySpec): Array<Record<string, unknown>> {
  const recordingRules = new Map(observability.recordingRules.map((rule) => [rule.id, rule]));
  return observability.warningAlerts.map((alert) => {
    const rule = recordingRules.get(alert.ruleId);
    return {
      ...alert,
      expression: rule === undefined ? null : nodeObservabilityWarningAlertExpression(rule, alert),
      recordingRule: rule === undefined ? null : rule.metric,
      lowSampleGuardExpression: rule === undefined ? null : `${nodeObservabilitySampleCountExpression(rule, { ...rule.matchLabels, ...alert.matchLabels })} >= ${alert.minSamples}`,
    };
  });
}

export function nodeObservabilityRecordingRuleExpression(rule: HwlabRuntimeObservabilityRecordingRuleSpec): string {
  const bucketGroupBy = uniqueStrings([...rule.groupBy, "le"]);
  return `histogram_quantile(${formatPrometheusNumber(rule.quantile)}, sum by (${bucketGroupBy.join(", ")}) (rate(${prometheusMetricSelector(`${rule.sourceMetric}_bucket`, rule.matchLabels)}[${rule.window}])))`;
}

function nodeObservabilitySampleCountExpression(rule: HwlabRuntimeObservabilityRecordingRuleSpec, matchLabels: Record<string, string>): string {
  const groupBy = uniqueStrings([...rule.groupBy]);
  return `sum by (${groupBy.join(", ")}) (increase(${prometheusMetricSelector(`${rule.sourceMetric}_count`, matchLabels)}[${rule.window}]))`;
}

export function nodeObservabilityWarningAlertExpression(rule: HwlabRuntimeObservabilityRecordingRuleSpec, alert: HwlabRuntimeObservabilityWarningAlertSpec): string {
  const sampleLabels = { ...rule.matchLabels, ...alert.matchLabels };
  const sampleGuard = `${nodeObservabilitySampleCountExpression(rule, sampleLabels)} >= ${alert.minSamples}`;
  const vectorMatch = rule.groupBy.length === 0 ? "" : ` on (${uniqueStrings([...rule.groupBy]).join(", ")})`;
  return `(${prometheusMetricSelector(rule.metric, alert.matchLabels)} > ${formatPrometheusNumber(alert.thresholdSeconds)}) and${vectorMatch} (${sampleGuard})`;
}

function prometheusMetricSelector(metric: string, labels: Record<string, string>): string {
  const selector = prometheusLabelSelector(labels);
  return selector.length === 0 ? metric : `${metric}${selector}`;
}

function prometheusLabelSelector(labels: Record<string, string>): string {
  const entries = Object.entries(labels);
  if (entries.length === 0) return "";
  return `{${entries.map(([key, value]) => `${key}${value.includes("|") ? "=~" : "="}"${escapePrometheusLabelValue(value)}"`).join(",")}}`;
}

function escapePrometheusLabelValue(value: string): string {
  return value.replace(/\\/gu, "\\\\").replace(/"/gu, "\\\"");
}

function formatPrometheusNumber(value: number): string {
  return Number.isInteger(value) ? String(value) : String(value);
}

function uniqueStrings(values: readonly string[]): string[] {
  return [...new Set(values)];
}
