// Force strict mode and setup for ESM
"use strict";
import {
  ChannelWorkerReconcileError
} from "./chunk-TIOE2OPE.js";
import {
  ChannelWorkerStartupError,
  ChannelWorkerStopError
} from "./chunk-6WGZDD67.js";
import {
  ChannelWebhookEnqueueError
} from "./chunk-KSZKSE23.js";
import "./chunk-TJTKSVIV.js";
import "./chunk-M5GB774H.js";
import "./chunk-5HBA2Z7V.js";
import "./chunk-ZQIYGQCG.js";
import "./chunk-UDXSXLER.js";
import "./chunk-T4TZQJ7W.js";
import "./chunk-H6XPXXMH.js";
import {
  init_esbuild_shims
} from "./chunk-5O2XNYP6.js";
import {
  __name
} from "./chunk-J2S4EL5Y.js";

// packages/cli/src/serve/channel-worker-manager.ts
init_esbuild_shims();
var ChannelWorkerControlError = class extends Error {
  static {
    __name(this, "ChannelWorkerControlError");
  }
  code;
  rolledBack;
  rollbackError;
  startupFailures;
  startupFailuresTruncated;
  constructor(code, message, details = {}) {
    super(message);
    this.name = "ChannelWorkerControlError";
    this.code = code;
    this.rolledBack = details.rolledBack;
    this.rollbackError = details.rollbackError;
    this.startupFailures = details.startupFailures?.map((failure) => ({
      ...failure
    }));
    this.startupFailuresTruncated = details.startupFailuresTruncated;
  }
};
var DISABLED_SNAPSHOT = {
  enabled: false,
  state: "disabled",
  channels: []
};
function cloneSelection(selection) {
  return selection.mode === "all" ? { mode: "all" } : { mode: "names", names: [...selection.names] };
}
__name(cloneSelection, "cloneSelection");
function selectionsEqual(left, right) {
  if (!left || left.mode !== right.mode) return false;
  if (left.mode === "all") return true;
  if (right.mode === "all" || left.names.length !== right.names.length) {
    return false;
  }
  return left.names.every((name, index) => name === right.names[index]);
}
__name(selectionsEqual, "selectionsEqual");
function isPartial(workers) {
  return workers.some((worker) => {
    if (!worker.requestedChannels) return false;
    const connected = new Set(worker.channels);
    return worker.requestedChannels.some((name) => !connected.has(name));
  });
}
__name(isPartial, "isPartial");
function errorMessage(error) {
  return error instanceof Error ? error.message : String(error);
}
__name(errorMessage, "errorMessage");
function startupFailureDetails(error) {
  if (!(error instanceof ChannelWorkerStartupError || error instanceof ChannelWorkerReconcileError) || !error.startupFailures) {
    return {};
  }
  return {
    startupFailures: error.startupFailures,
    ...error.startupFailuresTruncated ? { startupFailuresTruncated: true } : {}
  };
}
__name(startupFailureDetails, "startupFailureDetails");
function createChannelWorkerManager(opts) {
  let committedSelection;
  let pendingSelection;
  let transition = "idle";
  let group;
  let leaseReserved = opts.initialLeaseReserved === true;
  let draining = false;
  let hardKilled = false;
  let lane = Promise.resolve();
  const workspaceDrains = /* @__PURE__ */ new Set();
  const snapshot = /* @__PURE__ */ __name(() => ({
    enabled: committedSelection !== void 0 || group !== void 0 || leaseReserved,
    selection: committedSelection ? cloneSelection(committedSelection) : null,
    ...pendingSelection ? { pendingSelection: cloneSelection(pendingSelection) } : {},
    transition,
    workers: group?.snapshots() ?? []
  }), "snapshot");
  const notify = /* @__PURE__ */ __name(() => {
    opts.onStateChange?.(snapshot());
  }, "notify");
  const enqueue = /* @__PURE__ */ __name((operation) => {
    const result = lane.then(operation, operation);
    lane = result.then(
      () => void 0,
      () => void 0
    );
    return result;
  }, "enqueue");
  const drainingError = /* @__PURE__ */ __name(() => new ChannelWorkerControlError(
    "daemon_draining",
    "Daemon is shutting down."
  ), "drainingError");
  const reserve = /* @__PURE__ */ __name((selection) => {
    if (leaseReserved) return;
    opts.reserveLease(selection);
    leaseReserved = true;
  }, "reserve");
  const release = /* @__PURE__ */ __name(() => {
    if (!leaseReserved) return;
    opts.releaseLease();
    leaseReserved = false;
  }, "release");
  const setTransition = /* @__PURE__ */ __name((next, pending) => {
    transition = next;
    pendingSelection = pending ? cloneSelection(pending) : void 0;
    notify();
  }, "setTransition");
  const commit = /* @__PURE__ */ __name((selection, groups) => {
    committedSelection = selection ? cloneSelection(selection) : void 0;
    transition = "idle";
    pendingSelection = void 0;
    opts.onCommittedSelection?.(committedSelection, groups);
    notify();
  }, "commit");
  const classifyFailure = /* @__PURE__ */ __name((error, fallbackCode) => {
    if (error instanceof ChannelWorkerReconcileError) {
      return new ChannelWorkerControlError(
        error.stopFailed ? "channel_worker_stop_failed" : fallbackCode,
        error.message,
        {
          rolledBack: error.rolledBack,
          ...error.rollbackError ? { rollbackError: error.rollbackError } : {},
          ...startupFailureDetails(error)
        }
      );
    }
    return new ChannelWorkerControlError(
      error instanceof ChannelWorkerStopError ? "channel_worker_stop_failed" : fallbackCode,
      errorMessage(error),
      startupFailureDetails(error)
    );
  }, "classifyFailure");
  const applySelection = /* @__PURE__ */ __name(async (selection, initial) => {
    if (hardKilled) throw drainingError();
    const enabling = !snapshot().enabled;
    const replacing = committedSelection !== void 0;
    const sameSelection = selectionsEqual(committedSelection, selection);
    if (sameSelection && group?.isHealthy()) {
      return {
        changed: false,
        replaced: false,
        partial: isPartial(group.snapshots()),
        state: snapshot(),
        created: false
      };
    }
    setTransition(replacing ? "reconciling" : "starting", selection);
    let targetGroups;
    try {
      targetGroups = await opts.resolveGroups(
        selection,
        initial ? "initial" : "set"
      );
      if (hardKilled) throw drainingError();
      reserve(selection);
    } catch (error) {
      setTransition("idle");
      throw error;
    }
    if (!group) {
      let candidate;
      try {
        candidate = opts.createGroup(targetGroups);
      } catch (error) {
        let cleanupError;
        if (!initial) {
          try {
            release();
          } catch (releaseError) {
            cleanupError = releaseError;
          }
        }
        setTransition("idle");
        throw new ChannelWorkerControlError(
          "channel_worker_start_failed",
          errorMessage(error),
          cleanupError ? { rolledBack: false, rollbackError: errorMessage(cleanupError) } : { rolledBack: !initial }
        );
      }
      group = candidate;
      for (const workspaceCwd of workspaceDrains) {
        candidate.beginWorkspaceDrain(workspaceCwd);
      }
      notify();
      try {
        await candidate.start();
      } catch (error) {
        const startupDetails = startupFailureDetails(error);
        let cleanupError;
        try {
          await candidate.stop();
        } catch (stopError) {
          cleanupError = stopError;
        }
        if (!cleanupError) {
          if (!initial) {
            try {
              release();
            } catch (releaseError) {
              cleanupError = releaseError;
            }
          }
          if (!cleanupError) group = void 0;
        }
        setTransition("idle");
        throw new ChannelWorkerControlError(
          "channel_worker_start_failed",
          errorMessage(error),
          cleanupError ? {
            rolledBack: false,
            rollbackError: errorMessage(cleanupError),
            ...startupDetails
          } : { rolledBack: true, ...startupDetails }
        );
      }
      commit(selection, targetGroups);
      return {
        changed: true,
        replaced: false,
        partial: isPartial(candidate.snapshots()),
        state: snapshot(),
        created: enabling
      };
    }
    try {
      const result = await group.reconcile(targetGroups, {
        onRollingBack: /* @__PURE__ */ __name(() => setTransition("rolling_back", selection), "onRollingBack")
      });
      commit(selection, targetGroups);
      return {
        changed: result.changed || !sameSelection,
        replaced: !sameSelection,
        partial: isPartial(result.workers),
        state: snapshot(),
        created: enabling
      };
    } catch (error) {
      setTransition("idle");
      throw classifyFailure(error, "channel_worker_start_failed");
    }
  }, "applySelection");
  const manager = {
    async startInitial(selection) {
      if (draining) throw drainingError();
      await enqueue(async () => {
        await applySelection(selection, true);
      });
    },
    setSelection(selection) {
      if (draining) {
        return Promise.reject(drainingError());
      }
      return enqueue(() => applySelection(selection, false));
    },
    stopSelection() {
      if (draining) {
        return Promise.reject(drainingError());
      }
      return enqueue(async () => {
        const hadState = group !== void 0 || leaseReserved;
        if (!hadState) {
          return { changed: false, state: snapshot() };
        }
        setTransition("stopping");
        try {
          if (group) {
            await group.stop();
            group = void 0;
          }
          release();
        } catch (error) {
          setTransition("idle");
          throw classifyFailure(error, "channel_worker_stop_failed");
        }
        commit(void 0, []);
        return { changed: hadState, state: snapshot() };
      });
    },
    reload() {
      if (draining) {
        return Promise.reject(drainingError());
      }
      return enqueue(async () => {
        if (!group || !committedSelection) {
          throw new ChannelWorkerControlError(
            "channel_worker_not_enabled",
            "This daemon has no channel worker to reload."
          );
        }
        setTransition("reconciling", committedSelection);
        let targetGroups;
        try {
          targetGroups = await opts.resolveGroups(committedSelection, "reload");
        } catch (error) {
          setTransition("idle");
          throw error;
        }
        if (hardKilled) throw drainingError();
        try {
          await group.reconcile(targetGroups, {
            force: true,
            onRollingBack: /* @__PURE__ */ __name(() => setTransition("rolling_back", committedSelection), "onRollingBack")
          });
        } catch (error) {
          setTransition("idle");
          throw classifyFailure(error, "channel_worker_start_failed");
        }
        commit(committedSelection, targetGroups);
        const snapshots = group.snapshots();
        return snapshots.find((worker) => worker.primary) ?? snapshots[0] ?? { ...DISABLED_SNAPSHOT };
      });
    },
    state: snapshot,
    primarySnapshot: /* @__PURE__ */ __name(() => group?.primarySnapshot() ?? { ...DISABLED_SNAPSHOT }, "primarySnapshot"),
    snapshots: /* @__PURE__ */ __name(() => group?.snapshots() ?? [], "snapshots"),
    enqueueWebhookTask(task) {
      if (!group || draining) {
        return Promise.reject(
          new ChannelWebhookEnqueueError(
            "channel_worker_unavailable",
            draining ? "Daemon is shutting down." : "Channel worker is not running."
          )
        );
      }
      return group.enqueueWebhookTask(task);
    },
    beginWorkspaceDrain(workspaceCwd) {
      workspaceDrains.add(workspaceCwd);
      group?.beginWorkspaceDrain(workspaceCwd);
    },
    cancelWorkspaceDrain(workspaceCwd) {
      workspaceDrains.delete(workspaceCwd);
      group?.cancelWorkspaceDrain(workspaceCwd);
    },
    workspaceActivity(workspaceCwd) {
      return group?.workspaceActivity(workspaceCwd) ?? 0;
    },
    removeWorkspace(workspaceCwd) {
      return enqueue(async () => {
        try {
          await group?.removeWorkspace(workspaceCwd);
          notify();
        } finally {
          workspaceDrains.delete(workspaceCwd);
        }
      });
    },
    restoreWorkspace(workspaceCwd) {
      return enqueue(async () => {
        await group?.restoreWorkspace(workspaceCwd);
        notify();
      });
    },
    refreshWorkspaces() {
      return enqueue(async () => {
        if (!group || !committedSelection) return;
        setTransition("reconciling", committedSelection);
        let targetGroups;
        try {
          targetGroups = await opts.resolveGroups(committedSelection, "reload");
        } catch (error) {
          setTransition("idle");
          throw error;
        }
        if (hardKilled) throw drainingError();
        try {
          await group.reconcile(targetGroups);
        } catch (error) {
          setTransition("idle");
          throw classifyFailure(error, "channel_worker_start_failed");
        }
        commit(committedSelection, targetGroups);
      });
    },
    workerChanged: notify,
    shutdown() {
      draining = true;
      return enqueue(async () => {
        if (group || leaseReserved) setTransition("stopping");
        try {
          if (group) {
            await group.stop();
            group = void 0;
          }
          release();
        } catch (error) {
          setTransition("idle");
          throw classifyFailure(error, "channel_worker_stop_failed");
        }
        commit(void 0, []);
      });
    },
    killAllSync() {
      draining = true;
      hardKilled = true;
      group?.killAllSync();
      pendingSelection = void 0;
      transition = "idle";
      notify();
    }
  };
  return manager;
}
__name(createChannelWorkerManager, "createChannelWorkerManager");
export {
  ChannelWorkerControlError,
  createChannelWorkerManager
};
/**
 * @license
 * Copyright 2026 Qwen Team
 * SPDX-License-Identifier: Apache-2.0
 */
