type RuntimeDrainState = {
  draining: boolean;
  drainStartedAt: string | null;
  activeHttpRequestCount: number;
  activeWebSocketConnectionCount: number;
};

const state: RuntimeDrainState = {
  draining: false,
  drainStartedAt: null,
  activeHttpRequestCount: 0,
  activeWebSocketConnectionCount: 0,
};

function clampCount(value: number) {
  return Number.isFinite(value) && value > 0 ? Math.trunc(value) : 0;
}

export function beginRuntimeDrain() {
  state.draining = true;
  state.drainStartedAt = new Date().toISOString();
}

export function endRuntimeDrain() {
  state.draining = false;
  state.drainStartedAt = null;
}

export function isRuntimeDraining() {
  return state.draining;
}

export function trackHttpRequestStarted() {
  state.activeHttpRequestCount += 1;
}

export function trackHttpRequestFinished() {
  state.activeHttpRequestCount = clampCount(state.activeHttpRequestCount - 1);
}

export function trackWebSocketConnectionOpened() {
  state.activeWebSocketConnectionCount += 1;
}

export function trackWebSocketConnectionClosed() {
  state.activeWebSocketConnectionCount = clampCount(state.activeWebSocketConnectionCount - 1);
}

export function getRuntimeDrainSnapshot() {
  return {
    draining: state.draining,
    drainStartedAt: state.drainStartedAt,
    activeHttpRequestCount: state.activeHttpRequestCount,
    activeWebSocketConnectionCount: state.activeWebSocketConnectionCount,
  };
}
