import {
  JOB_RUN_SERVICE
} from "./chunk-ZPL74UQN.js";
import {
  BRIDGE_DELIVERY_REPO
} from "./chunk-4LH67P4U.js";
import {
  EVENT_READ_PORT
} from "./chunk-H5NH7KPE.js";
import {
  INTEGRATION_CURSOR_STORE,
  INTEGRATION_RUN_RECORDER
} from "./chunk-S7C6TIIF.js";
import {
  __decorateClass,
  __decorateParam,
  __publicField
} from "./chunk-2E224ZSN.js";

// runtime/subsystems/observability/observability.service.ts
import { Inject, Injectable, Optional } from "@nestjs/common";
var MAX_TIMELINE_PAGES = 50;
var ObservabilityService = class {
  constructor(jobRuns, bridge, integrationRuns, cursors, events) {
    this.jobRuns = jobRuns;
    this.bridge = bridge;
    this.integrationRuns = integrationRuns;
    this.cursors = cursors;
    this.events = events;
  }
  jobRuns;
  bridge;
  integrationRuns;
  cursors;
  events;
  async getPoolDepths(tenantId) {
    if (!this.jobRuns) return [];
    return this.jobRuns.countByPoolAndStatus(tenantId);
  }
  async getRecentFailedJobs(limit, tenantId) {
    if (!this.jobRuns) return [];
    return this.jobRuns.listRecentFailed(limit, tenantId);
  }
  async getBridgeDeliveryHistogram(windowHours, tenantId) {
    if (!this.bridge) return { ...ObservabilityService.EMPTY_HISTOGRAM };
    return this.bridge.getStatusHistogram(windowHours, tenantId);
  }
  async getRecentIntegrationRuns(limit, subscriptionId, tenantId) {
    if (!this.integrationRuns) return [];
    return this.integrationRuns.listRecent(limit, subscriptionId, tenantId);
  }
  async getCursors(tenantId) {
    if (!this.cursors) return [];
    return this.cursors.listAll(tenantId);
  }
  async listJobRuns(query) {
    if (!this.jobRuns) {
      return { ...ObservabilityService.EMPTY_JOB_RUN_PAGE };
    }
    return this.jobRuns.listJobRuns(query);
  }
  async listEvents(query) {
    if (!this.events) {
      return { ...ObservabilityService.EMPTY_EVENT_PAGE };
    }
    return this.events.listEvents(query);
  }
  async getCorrelationTimeline(rootRunId, tenantId) {
    const runs = await this.collectRuns(rootRunId, tenantId);
    const events = await this.collectEvents(rootRunId, tenantId);
    const entries = [
      ...runs.map(
        (run) => ({
          kind: "job_run",
          at: run.createdAt,
          run
        })
      ),
      ...events.map(
        (event) => ({
          kind: "event",
          at: event.occurredAt,
          event
        })
      )
    ];
    entries.sort((a, b) => {
      const dt = a.at.getTime() - b.at.getTime();
      if (dt !== 0) return dt;
      if (a.kind === b.kind) return 0;
      return a.kind === "job_run" ? -1 : 1;
    });
    const startedAt = entries.length > 0 ? entries[0].at : null;
    const lastActivityAt = entries.length > 0 ? entries[entries.length - 1].at : null;
    return {
      rootRunId,
      entries,
      summary: {
        runCount: runs.length,
        eventCount: events.length,
        startedAt,
        lastActivityAt
      }
    };
  }
  /**
   * Drain every `job_run` sharing `rootRunId` by walking the keyset cursor.
   * Empty when the jobs subsystem is absent.
   */
  async collectRuns(rootRunId, tenantId) {
    if (!this.jobRuns) return [];
    const out = [];
    let cursor;
    for (let page = 0; page < MAX_TIMELINE_PAGES; page += 1) {
      const result = await this.jobRuns.listJobRuns({
        rootRunId,
        tenantId,
        cursor
      });
      out.push(...result.items);
      if (!result.nextCursor) break;
      cursor = result.nextCursor;
    }
    return out;
  }
  /**
   * Drain every `domain_event` whose `metadata.rootRunId` matches by walking
   * the keyset cursor. Empty when the events read port is absent.
   */
  async collectEvents(rootRunId, tenantId) {
    if (!this.events) return [];
    const out = [];
    let cursor;
    for (let page = 0; page < MAX_TIMELINE_PAGES; page += 1) {
      const result = await this.events.listEvents({
        rootRunId,
        tenantId,
        cursor
      });
      out.push(...result.items);
      if (!result.nextCursor) break;
      cursor = result.nextCursor;
    }
    return out;
  }
};
/**
 * All-zero histogram used when the bridge subsystem is absent. Matches
 * the bridge protocol's "fixed keys, zero-filled" contract so consumers
 * never branch on presence.
 */
__publicField(ObservabilityService, "EMPTY_HISTOGRAM", {
  pending: 0,
  delivered: 0,
  skipped: 0,
  failed: 0
});
/** Empty page used when a sibling read port is absent. */
__publicField(ObservabilityService, "EMPTY_JOB_RUN_PAGE", {
  items: [],
  nextCursor: null
});
__publicField(ObservabilityService, "EMPTY_EVENT_PAGE", {
  items: [],
  nextCursor: null
});
ObservabilityService = __decorateClass([
  Injectable(),
  __decorateParam(0, Optional()),
  __decorateParam(0, Inject(JOB_RUN_SERVICE)),
  __decorateParam(1, Optional()),
  __decorateParam(1, Inject(BRIDGE_DELIVERY_REPO)),
  __decorateParam(2, Optional()),
  __decorateParam(2, Inject(INTEGRATION_RUN_RECORDER)),
  __decorateParam(3, Optional()),
  __decorateParam(3, Inject(INTEGRATION_CURSOR_STORE)),
  __decorateParam(4, Optional()),
  __decorateParam(4, Inject(EVENT_READ_PORT))
], ObservabilityService);

export {
  ObservabilityService
};
//# sourceMappingURL=chunk-W2UIDI3R.js.map