/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import { randomUUID } from 'node:crypto';
import { homedir } from 'node:os';
import { join, resolve } from 'node:path';
import { isDeepStrictEqual } from 'node:util';
import { truncateUtf8 } from '@maka/core/diagnostic-log';
import { generalizedErrorMessage } from '@maka/core/redaction';
import {
  activateRuntimeHostManagedDeployment,
  connectRemoteRuntimeHost,
  ensureRuntimeHostPeerIdentity,
  RuntimeHostOperationError,
} from '@maka/runtime-host/client';
import {
  RuntimeHostManagedDeploymentError as RuntimeHostDeploymentAuthorityError,
  encodeRuntimeHostSetupFrame,
  isSha512PackageIntegrity,
  resolveRuntimeHostManagedDeployment,
  resolveRuntimeHostManagedDeploymentAuthority,
  runtimeHostManagedOperatorCommand,
  RUNTIME_HOST_SETUP_ERROR_CODE_MAX_BYTES,
  RUNTIME_HOST_SETUP_ERROR_MESSAGE_MAX_BYTES,
  type RuntimeHostManagedDeploymentConfig,
  type RuntimeHostNodeOperatorCommand,
  type RuntimeHostSetupFrame,
  type RuntimeHostSetupPhase,
} from '@maka/runtime-host/operator';
import {
  INTERACTIVE_RUNTIME_HOST_COMPOSITION_ID,
  RUNTIME_HOST_PROTOCOL_VERSION,
} from '@maka/runtime-host/protocol';
import {
  prepareRuntimeHostAccessCredential,
  replaceRuntimeHostAccessCredential,
  revokeRuntimeHostAccessCredential,
  RuntimeHostAccessUnavailableError,
  type RuntimeHostAccessPreset,
} from './runtime-host-access-command.js';
import {
  convergeRuntimeHostManagedOperator,
  verifyRuntimeHostManagedOperator,
  isRuntimeHostDevelopmentPackageVersion,
  openRuntimeHostManagedPackageDeployment,
  prepareRuntimeHostManagedPackageDeployment,
  pruneRuntimeHostManagedPackages,
  removeRuntimeHostManagedDeployment,
  resolveRuntimeHostManagedPackageCliPath,
  resolveRuntimeHostManagedControlRoot,
  resolveRuntimeHostManagedDeploymentRoot,
  restoreRuntimeHostLegacyManagedOperator,
  RuntimeHostManagedDeploymentError,
} from './runtime-host-managed-deployment.js';
import {
  RuntimeHostUpdatePackageError,
  withRuntimeHostRegistryUpdatePackage,
} from './runtime-host-update-package.js';
import {
  readRuntimeHostManagedUpdatePolicy,
  writeRuntimeHostManagedUpdatePolicy,
} from './runtime-host-update-policy-store.js';
import {
  resolveRuntimeHostRegistryUpdateCandidate,
  RuntimeHostUpdateDiscoveryError,
  type RuntimeHostUpdateCandidate,
} from './runtime-host-update-discovery.js';
import { repairStorageRootAfterRemount, resolveStorageRoot } from '@maka/storage/root-authority';
import {
  createPlatformRuntimeHostServiceBackend,
  discoverRuntimeHostLifecycleProvider,
  resolveRuntimeHostLifecycleProvider,
} from './runtime-host-service-management-command.js';
import {
  allocateRuntimeHostLoopbackPort,
  allocateRuntimeHostPeerPort,
  effectiveRuntimeHostProjectDirectoryRoots,
  manageRuntimeHostService,
  readRuntimeHostManagedServiceConfig,
  removeRuntimeHostServiceFile,
  resolveRuntimeHostManagedServiceConfigPath,
  resolveRuntimeHostManagedServiceId,
  resolveRuntimeHostManagedProjectDirectoryRoots,
  RuntimeHostServiceManagerError,
  withRuntimeHostManagedServiceDeploymentLock,
  withRuntimeHostManagedServiceLifecycleLock,
  type RuntimeHostManagedServiceResult,
  type RuntimeHostManagedServiceConfig,
  type RuntimeHostManagedServiceTarget,
  type RuntimeHostServiceBackend,
} from './runtime-host-service-manager.js';
import { expandWildcardListenAddresses } from './runtime-host-peer-management-command.js';
import {
  canDiscardRuntimeHostLifecycleDesiredArtifacts,
  replaceRuntimeHostLifecycle,
  resolveRecoverableRuntimeHostManagedDeployment,
  RUNTIME_HOST_READY_TIMEOUT_MS,
  RuntimeHostLifecycleTransactionError,
  type RuntimeHostLifecycleTransactionDeps,
} from './runtime-host-lifecycle-transaction.js';
import type {
  RuntimeHostLifecycleProvider,
  RuntimeHostLifecycleProviderOffer,
} from './runtime-host-lifecycle-provider.js';
import {
  resolveRuntimeHostManagedPeerKeyPath,
  resolveRuntimeHostNativePath,
} from './runtime-host-peer-artifact.js';
import { activateRuntimeHostManagedDeploymentWithReconciliation } from './runtime-host-activation-command.js';

const SETUP_LOCK_TIMEOUT_MS = 5 * 60_000;
const PAIRING_AVAILABILITY_POLL_MS = 100;

export interface RuntimeHostSetupCliOptions {
  readonly json: boolean;
  readonly clientDataRoot: string;
  readonly defaultRootPath: string;
  readonly sourcePackageRoot: string;
  readonly version: string;
  readonly sourcePackageIntegrity?: string;
  readonly principalId: string;
  readonly preset: RuntimeHostAccessPreset;
  readonly lifecycle?: 'supervised' | 'on_demand';
  readonly deferPairingCommit?: boolean;
  readonly bindPairingToClient?: boolean;
  readonly repairRootAfterRemount?: true;
  readonly updateExisting?: boolean;
  readonly reuseExistingEnvironment?: boolean;
  readonly allowInterruptActiveTasks?: boolean;
  readonly rootPath?: string;
  readonly projectDirectoryRoots?: readonly {
    readonly label: string;
    readonly path: string;
  }[];
  readonly websocketPort?: number;
  readonly websocketPath?: string;
  readonly directPeer?: {
    readonly coordinationRelays: readonly string[];
  };
  readonly expectedTarget?: RuntimeHostManagedServiceTarget;
}

interface RuntimeHostSetupDeps {
  readonly manageService: typeof manageRuntimeHostService;
  readonly createBackend: (serviceId: string, clientDataRoot: string) => RuntimeHostServiceBackend;
  readonly discoverLifecycleProvider: (
    rootId: string,
  ) => Promise<RuntimeHostLifecycleProviderOffer>;
  readonly resolveLifecycleProvider: (
    config: RuntimeHostManagedDeploymentConfig,
  ) => RuntimeHostLifecycleProvider;
  readonly replaceLifecycle: typeof replaceRuntimeHostLifecycle;
  readonly openDeployment: typeof openRuntimeHostManagedPackageDeployment;
  readonly prepareDeployment: typeof prepareRuntimeHostManagedPackageDeployment;
  readonly prunePackages: typeof pruneRuntimeHostManagedPackages;
  readonly prepareCredential: typeof prepareRuntimeHostAccessCredential;
  readonly replaceCredential: typeof replaceRuntimeHostAccessCredential;
  readonly revokeCredential: typeof revokeRuntimeHostAccessCredential;
  readonly verifyCredential: typeof verifyRuntimeHostSetupCredential;
  readonly activateDesired: typeof activateRuntimeHostManagedDeployment;
  readonly activateManaged: typeof activateRuntimeHostManagedDeployment;
  readonly convergeOperator: typeof convergeRuntimeHostManagedOperator;
  readonly verifyOperator: typeof verifyRuntimeHostManagedOperator;
  readonly resolveRegistryCandidate: typeof resolveRuntimeHostRegistryUpdateCandidate;
  readonly withRegistryPackage: typeof withRuntimeHostRegistryUpdatePackage;
  readonly ensurePeerIdentity: typeof ensureRuntimeHostPeerIdentity;
  readonly resolvePeerNativePath: typeof resolveRuntimeHostNativePath;
  readonly allocateLoopbackPort: typeof allocateRuntimeHostLoopbackPort;
  readonly allocatePeerPort: typeof allocateRuntimeHostPeerPort;
  readonly writeOutput: (value: string) => unknown;
  readonly writeError: (value: string) => unknown;
}

class RuntimeHostSetupError extends Error {
  constructor(
    readonly code: string,
    message: string,
    options?: ErrorOptions,
  ) {
    super(message, options);
    this.name = 'RuntimeHostSetupError';
  }
}

interface ResolvedRuntimeHostSetupPackage {
  readonly candidate: RuntimeHostUpdateCandidate;
  use<T>(operation: (packageRoot: string) => Promise<T>): Promise<T>;
}

async function resolveRuntimeHostSetupPackage(
  options: RuntimeHostSetupCliOptions,
  deps: Pick<RuntimeHostSetupDeps, 'resolveRegistryCandidate' | 'withRegistryPackage'>,
): Promise<ResolvedRuntimeHostSetupPackage> {
  if (isRuntimeHostDevelopmentPackageVersion(options.version)) {
    const integrity = options.sourcePackageIntegrity;
    if (typeof integrity !== 'string' || !isSha512PackageIntegrity(integrity)) {
      throw new RuntimeHostSetupError(
        'development_package_unverified',
        'The Runtime Host development package is missing exact artifact evidence',
      );
    }
    return {
      candidate: {
        kind: 'npm_registry',
        version: options.version,
        integrity,
      },
      use: (operation) => operation(options.sourcePackageRoot),
    };
  }
  const candidate = await deps.resolveRegistryCandidate({
    kind: 'exact',
    version: options.version,
  });
  return {
    candidate,
    use: (operation) => deps.withRegistryPackage(candidate, operation),
  };
}

export async function runRuntimeHostSetupCli(
  options: RuntimeHostSetupCliOptions,
  overrides: Partial<RuntimeHostSetupDeps> = {},
): Promise<number> {
  const deps: RuntimeHostSetupDeps = {
    manageService: manageRuntimeHostService,
    createBackend: createPlatformRuntimeHostServiceBackend,
    discoverLifecycleProvider: discoverRuntimeHostLifecycleProvider,
    resolveLifecycleProvider: resolveRuntimeHostLifecycleProvider,
    replaceLifecycle: replaceRuntimeHostLifecycle,
    openDeployment: openRuntimeHostManagedPackageDeployment,
    prepareDeployment: prepareRuntimeHostManagedPackageDeployment,
    prunePackages: pruneRuntimeHostManagedPackages,
    prepareCredential: prepareRuntimeHostAccessCredential,
    replaceCredential: replaceRuntimeHostAccessCredential,
    revokeCredential: revokeRuntimeHostAccessCredential,
    verifyCredential: verifyRuntimeHostSetupCredential,
    activateDesired: (input) =>
      activateRuntimeHostManagedDeployment(input, {
        reconcileActivation: async () => undefined,
      }),
    activateManaged: (input) =>
      activateRuntimeHostManagedDeploymentWithReconciliation(input, {
        deploymentLockHeld: true,
      }),
    convergeOperator: convergeRuntimeHostManagedOperator,
    verifyOperator: verifyRuntimeHostManagedOperator,
    resolveRegistryCandidate: resolveRuntimeHostRegistryUpdateCandidate,
    withRegistryPackage: withRuntimeHostRegistryUpdatePackage,
    ensurePeerIdentity: ensureRuntimeHostPeerIdentity,
    resolvePeerNativePath: resolveRuntimeHostNativePath,
    allocateLoopbackPort: allocateRuntimeHostLoopbackPort,
    allocatePeerPort: allocateRuntimeHostPeerPort,
    writeOutput: (value) => process.stdout.write(value),
    writeError: (value) => process.stderr.write(value),
    ...overrides,
  };
  const emit = createEmitter(options.json, deps);
  try {
    const rootId = await resolveRuntimeHostSetupRootId(options);
    const controlRoot = resolveRuntimeHostManagedControlRoot(rootId);
    await withRuntimeHostManagedServiceDeploymentLock(
      options.clientDataRoot,
      () =>
        withRuntimeHostManagedServiceLifecycleLock(
          options.clientDataRoot,
          () =>
            withRuntimeHostManagedServiceDeploymentLock(
              controlRoot,
              () =>
                withRuntimeHostManagedServiceLifecycleLock(
                  controlRoot,
                  () => runRuntimeHostSetupLocked(options, deps, emit, rootId),
                  SETUP_LOCK_TIMEOUT_MS,
                ),
              SETUP_LOCK_TIMEOUT_MS,
            ),
          SETUP_LOCK_TIMEOUT_MS,
        ),
      SETUP_LOCK_TIMEOUT_MS,
    );
    return 0;
  } catch (error) {
    const failure = setupFailure(error);
    emit({ kind: 'error', error: failure });
    return 1;
  }
}

async function resolveRuntimeHostSetupRootId(options: RuntimeHostSetupCliOptions): Promise<string> {
  const legacyRootPath = (await readOptionalLegacyServiceConfig(options.clientDataRoot))?.rootPath;
  const path = resolve(
    options.rootPath ??
      legacyRootPath ??
      options.expectedTarget?.rootPath ??
      options.defaultRootPath,
  );
  if (options.repairRootAfterRemount) {
    await repairStorageRootAfterRemount({ path, kind: 'interactive' });
  }
  return (await resolveStorageRoot({ path, kind: 'interactive' })).rootId;
}

async function readOptionalLegacyServiceConfig(
  clientDataRoot: string,
): Promise<RuntimeHostManagedServiceConfig | null> {
  try {
    return await readRuntimeHostManagedServiceConfig(
      resolveRuntimeHostManagedServiceConfigPath(clientDataRoot),
    );
  } catch (error) {
    if (error instanceof RuntimeHostServiceManagerError && error.code === 'not_installed') {
      return null;
    }
    throw error;
  }
}

async function runRuntimeHostSetupLocked(
  options: RuntimeHostSetupCliOptions,
  deps: RuntimeHostSetupDeps,
  emit: SetupEmitter,
  rootId: string,
): Promise<void> {
  if (options.reuseExistingEnvironment) {
    if (options.lifecycle !== 'on_demand' || options.updateExisting) {
      throw new RuntimeHostSetupError(
        'invalid_setup',
        'Environment discovery cannot replace a deployment',
      );
    }
    const existing = await resolveRuntimeHostManagedDeploymentAuthority(rootId);
    if (existing) {
      const { config, capability } = await resolveRuntimeHostManagedDeployment(rootId);
      assertCanonicalSetupTarget(options.expectedTarget, rootId, capability.canonicalPath);
      assertExpectedDeploymentGeneration(options.expectedTarget, config);
      // The binding comes from canonical authority. The installed operator validates
      // its own projection when connected; discovery must not rewrite an older launcher.
      emit({
        kind: 'existing_environment',
        version: config.launch.package.version,
        serviceId: rootId,
        deploymentId: config.deploymentId,
        rootId,
        rootPath: capability.canonicalPath,
        operator: runtimeHostManagedOperatorCommand(
          config,
          process.platform === 'win32' ? 'win32' : 'posix',
        ),
      });
      return;
    }
  }
  if (options.lifecycle === 'on_demand') {
    await runRuntimeHostOnDemandSetupLocked(options, deps, emit);
    return;
  }
  const target = await runRuntimeHostSupervisedSetupLocked(options, deps, emit);
  await pairAndVerifyRuntimeHostSetup(options, target, deps, emit);
}

async function runRuntimeHostSupervisedSetupLocked(
  options: RuntimeHostSetupCliOptions,
  deps: RuntimeHostSetupDeps,
  emit: SetupEmitter,
): Promise<{
  readonly serviceId: string;
  readonly deploymentId: string;
  readonly operator: RuntimeHostNodeOperatorCommand;
  readonly rootPath: string;
  readonly endpoint: string;
  readonly directPeer?: {
    readonly peerId: string;
    readonly routeHints: readonly string[];
    readonly coordinationRelays: readonly string[];
  };
}> {
  emit({ kind: 'progress', phase: 'checking_environment' });
  const legacyServiceId = resolveRuntimeHostManagedServiceId(options.clientDataRoot);
  const legacyConfig = await readOptionalLegacyServiceConfig(options.clientDataRoot);
  const legacyBackend = legacyConfig
    ? deps.createBackend(legacyServiceId, options.clientDataRoot)
    : undefined;
  const legacyCommon = {
    clientDataRoot: options.clientDataRoot,
    defaultRootPath: options.defaultRootPath,
    nodePath: process.execPath,
    cliPath: join(options.sourcePackageRoot, 'dist', 'cli.js'),
    ...(options.expectedTarget
      ? { expectedTarget: legacyManagedTarget(options.expectedTarget, legacyServiceId) }
      : {}),
  } as const;
  const legacyStatus = legacyBackend
    ? await deps.manageService({ ...legacyCommon, action: 'status' }, legacyBackend)
    : undefined;
  const capability = await resolveStorageRoot({
    path: resolve(
      options.rootPath ??
        legacyConfig?.rootPath ??
        options.expectedTarget?.rootPath ??
        options.defaultRootPath,
    ),
    kind: 'interactive',
  });
  assertCanonicalSetupTarget(options.expectedTarget, capability.rootId, capability.canonicalPath);
  const lifecycleDeps: RuntimeHostLifecycleTransactionDeps = {
    convergeOperator: (currentConfig, desiredConfig) =>
      deps.convergeOperator(currentConfig, desiredConfig),
    verifyOperator: deps.verifyOperator,
    resolveProvider: deps.resolveLifecycleProvider,
    ...(legacyConfig && legacyBackend
      ? legacyMigrationDeps(legacyConfig, legacyBackend, legacyServiceId, options.clientDataRoot)
      : {}),
  };
  const recovered = await resolveRecoverableRuntimeHostManagedDeployment(
    capability.rootId,
    lifecycleDeps,
    {
      ...(legacyBackend ? { retirementSupervisor: legacyBackend } : {}),
      ...(legacyBackend
        ? {
            activatePrevious: () =>
              deps
                .manageService({ ...legacyCommon, action: 'start' }, legacyBackend)
                .then(() => undefined),
          }
        : {}),
      ...(options.expectedTarget ? { expectedTarget: options.expectedTarget } : {}),
    },
  );
  const current = recovered.kind === 'active' ? recovered.config : undefined;
  assertExpectedDeploymentGeneration(options.expectedTarget, current);
  const legacyToMigrate = current ? null : legacyConfig;
  if (current && legacyBackend) await assertLegacyArtifactsAbsent(legacyBackend);
  if (legacyToMigrate && legacyStatus) {
    await assertCompatibleExistingVersion(legacyStatus, options.version);
  }
  if (current && current.launch.package.version !== options.version && !options.updateExisting) {
    throw new RuntimeHostSetupError(
      'version_change_requires_update',
      `Runtime Host ${current.launch.package.version} is already installed; changing to ${options.version} requires the update workflow`,
    );
  }

  const resolvedPackage = await resolveRuntimeHostSetupPackage(options, deps);
  const { candidate } = resolvedPackage;
  const packageChanged = current !== undefined && !sameExactPackage(current, candidate);
  if (current && packageChanged && !options.updateExisting) {
    throw new RuntimeHostSetupError(
      'version_change_requires_update',
      `Runtime Host ${current.launch.package.version} is already installed; changing its exact package requires the update workflow`,
    );
  }
  const lifecycleOffer: RuntimeHostLifecycleProviderOffer =
    current?.lifecycle.mode === 'supervised'
      ? {
          provider: deps.resolveLifecycleProvider(current),
          availability: current.lifecycle.availability,
        }
      : await deps.discoverLifecycleProvider(capability.rootId);
  return resolvedPackage.use(async (packageRoot) => {
    emit({ kind: 'progress', phase: 'installing_package' });
    const deployment = await deps.prepareDeployment({
      serviceId: capability.rootId,
      clientDataRoot: options.clientDataRoot,
      sourcePackageRoot: packageRoot,
      version: candidate.version,
      packageIntegrity: candidate.integrity,
      ...(current ? { deploymentRoot: current.deploymentRoot } : {}),
    });
    let committed = false;
    try {
      const desired = await prepareSupervisedDeploymentConfig(
        options,
        deps,
        capability,
        deployment.cliPath,
        deployment.root,
        candidate,
        current,
        legacyToMigrate,
        lifecycleOffer,
      );
      if (
        current &&
        !sameDesiredManagedDeployment(current, desired) &&
        !options.updateExisting &&
        current.lifecycle.mode === 'supervised'
      ) {
        throw new RuntimeHostSetupError(
          'configuration_changed',
          'Change an existing supervised Runtime Host through its explicit configure or update workflow',
        );
      }
      emit({ kind: 'progress', phase: 'installing_service' });
      if (legacyToMigrate && legacyBackend) {
        await legacyBackend.verifyDeployment(legacyToMigrate, {
          acceptLegacyConfigLaunch: true,
        });
      }
      const replacement = await deps.replaceLifecycle({
        operation: legacyToMigrate
          ? 'legacy_migration'
          : current
            ? packageChanged
              ? 'update'
              : isDeepStrictEqual(current.lifecycle, desired.lifecycle)
                ? 'configure'
                : 'lifecycle_change'
            : 'install',
        ...(current ? { current } : {}),
        desired,
        ...(legacyToMigrate && legacyBackend ? { retirementSupervisor: legacyBackend } : {}),
        ...(legacyToMigrate && legacyBackend
          ? {
              activatePrevious: () =>
                deps
                  .manageService({ ...legacyCommon, action: 'start' }, legacyBackend)
                  .then(() => undefined),
            }
          : {}),
        allowInterruptActiveTasks: options.allowInterruptActiveTasks === true,
        deps: lifecycleDeps,
      });
      if (replacement.kind === 'active_tasks') {
        throw new RuntimeHostSetupError(
          'active_tasks',
          'Runtime Host setup is waiting for active work to finish',
        );
      }
      committed = true;
      if (legacyConfig) {
        await removeRuntimeHostServiceFile(
          resolveRuntimeHostManagedServiceConfigPath(options.clientDataRoot),
          'legacy service config',
        );
        if (
          legacyConfig.managedDeploymentRoot &&
          resolve(legacyConfig.managedDeploymentRoot) !== resolve(deployment.root)
        ) {
          await removeRuntimeHostManagedDeployment(
            legacyConfig.managedDeploymentRoot,
            legacyServiceId,
          );
        }
      }
      await deps.prunePackages(desired);
      const websocket = desired.listeners.websocket;
      if (!websocket) {
        throw new RuntimeHostSetupError(
          'service_not_ready',
          'Supervised Runtime Host setup requires a WebSocket listener',
        );
      }
      const directPeer = desired.listeners.directPeer?.enabled
        ? desired.listeners.directPeer
        : undefined;
      return {
        serviceId: capability.rootId,
        deploymentId: desired.deploymentId,
        operator: runtimeHostManagedOperatorCommand(
          desired,
          process.platform === 'win32' ? 'win32' : 'posix',
        ),
        rootPath: capability.canonicalPath,
        endpoint: websocketUrl(websocket),
        ...(directPeer
          ? {
              directPeer: {
                peerId: directPeer.peerId,
                routeHints: expandWildcardListenAddresses(directPeer.listenAddresses),
                coordinationRelays: [...directPeer.coordinationRelays],
              },
            }
          : {}),
      };
    } catch (error) {
      if (!committed && canDiscardRuntimeHostLifecycleDesiredArtifacts(error)) {
        if (current && packageChanged) {
          await deployment.rollback().catch(() => undefined);
        } else if (!current) {
          await removeRuntimeHostManagedDeployment(deployment.root, capability.rootId).catch(
            () => undefined,
          );
        }
      }
      throw error;
    }
  });
}

async function prepareSupervisedDeploymentConfig(
  options: RuntimeHostSetupCliOptions,
  deps: RuntimeHostSetupDeps,
  capability: Awaited<ReturnType<typeof resolveStorageRoot>>,
  cliPath: string,
  deploymentRoot: string,
  candidate: { readonly version: string; readonly integrity: string },
  current: RuntimeHostManagedDeploymentConfig | undefined,
  legacy: RuntimeHostManagedServiceConfig | null,
  offer: RuntimeHostLifecycleProviderOffer,
): Promise<RuntimeHostManagedDeploymentConfig> {
  const projectDirectoryRoots = await resolveRuntimeHostManagedProjectDirectoryRoots(
    options.projectDirectoryRoots ??
      current?.projectDirectoryRoots ??
      (legacy
        ? effectiveRuntimeHostProjectDirectoryRoots(legacy)
        : [{ label: '~', path: resolve(homedir()) }]),
  );
  const currentWebSocket = current?.listeners.websocket;
  const websocketPort =
    options.websocketPort ??
    (currentWebSocket && currentWebSocket.port > 0
      ? currentWebSocket.port
      : legacy?.websocket.port) ??
    (await deps.allocateLoopbackPort());
  const directPeer = await prepareSupervisedDirectPeer(
    options,
    deps,
    cliPath,
    deploymentRoot,
    current?.listeners.directPeer,
  );
  const draft: RuntimeHostManagedDeploymentConfig = {
    schemaVersion: 1,
    state: 'active',
    deploymentId: current?.deploymentId ?? randomUUID(),
    configRevision: current ? current.configRevision + 1 : 1,
    deploymentRoot,
    root: { path: capability.canonicalPath, id: capability.rootId },
    projectDirectoryRoots: [...projectDirectoryRoots],
    launch: {
      kind: 'exact_package',
      nodePath: current?.launch.nodePath ?? process.execPath,
      package: {
        kind: 'npm_registry',
        version: candidate.version,
        integrity: candidate.integrity,
      },
    },
    listeners: {
      localIpc: true,
      websocket: {
        host: '127.0.0.1',
        port: websocketPort,
        path:
          options.websocketPath ??
          currentWebSocket?.path ??
          legacy?.websocket.path ??
          '/runtime-host',
      },
      ...(directPeer ? { directPeer } : {}),
    },
    lifecycle: {
      mode: 'supervised',
      provider: offer.provider.supervisor.provider,
      availability: offer.availability,
    },
    reconciliation: {
      trigger: 'scheduled',
      provider: offer.provider.reconciliationTrigger.provider,
    },
  };
  return draft;
}

async function prepareSupervisedDirectPeer(
  options: RuntimeHostSetupCliOptions,
  deps: RuntimeHostSetupDeps,
  cliPath: string,
  deploymentRoot: string,
  current: RuntimeHostManagedDeploymentConfig['listeners']['directPeer'],
): Promise<RuntimeHostManagedDeploymentConfig['listeners']['directPeer']> {
  if (!options.directPeer && !current) return undefined;
  const keyPath = current?.keyPath ?? resolveRuntimeHostManagedPeerKeyPath(deploymentRoot);
  const peerId = await deps.ensurePeerIdentity({
    nativePath: await deps.resolvePeerNativePath(cliPath),
    keyPath,
  });
  const expectedPeerId = current?.peerId;
  if (expectedPeerId && expectedPeerId !== peerId) {
    throw new RuntimeHostSetupError(
      'invalid_config',
      'The Runtime Host peer identity does not match its persisted deployment',
    );
  }
  return {
    enabled: options.directPeer ? true : (current?.enabled ?? true),
    keyPath,
    peerId,
    listenAddresses: [
      ...(current?.listenAddresses ?? [
        `/ip4/0.0.0.0/udp/${String(await deps.allocatePeerPort())}/quic-v1`,
      ]),
    ],
    coordinationRelays: [
      ...(options.directPeer?.coordinationRelays ?? current?.coordinationRelays ?? []),
    ],
    automaticRelayDiscovery: current?.automaticRelayDiscovery ?? true,
    webRtcStunPolicy: current?.webRtcStunPolicy ?? { kind: 'default' },
  };
}

function sameDesiredManagedDeployment(
  current: RuntimeHostManagedDeploymentConfig,
  desired: RuntimeHostManagedDeploymentConfig,
): boolean {
  const { configRevision: _currentRevision, ...currentState } = current;
  const { configRevision: _desiredRevision, ...desiredState } = desired;
  return isDeepStrictEqual(currentState, desiredState);
}

async function runRuntimeHostOnDemandSetupLocked(
  options: RuntimeHostSetupCliOptions,
  deps: RuntimeHostSetupDeps,
  emit: SetupEmitter,
): Promise<void> {
  if (options.directPeer) {
    throw new RuntimeHostSetupError(
      'unsupported_lifecycle_configuration',
      'On-demand setup does not support a Direct peer listener',
    );
  }
  emit({ kind: 'progress', phase: 'checking_environment' });
  const legacyServiceId = resolveRuntimeHostManagedServiceId(options.clientDataRoot);
  const legacyConfig = await readOptionalLegacyServiceConfig(options.clientDataRoot);
  const legacyBackend = legacyConfig
    ? deps.createBackend(legacyServiceId, options.clientDataRoot)
    : undefined;
  let legacyStatus: RuntimeHostManagedServiceResult | undefined;
  if (legacyBackend) {
    legacyStatus = await deps.manageService(
      {
        action: 'status',
        clientDataRoot: options.clientDataRoot,
        defaultRootPath: options.defaultRootPath,
        nodePath: process.execPath,
        cliPath: join(options.sourcePackageRoot, 'dist', 'cli.js'),
        ...(options.expectedTarget
          ? { expectedTarget: legacyManagedTarget(options.expectedTarget, legacyServiceId) }
          : {}),
      },
      legacyBackend,
    );
  }
  const capability = await resolveStorageRoot({
    path: resolve(
      options.rootPath ??
        legacyConfig?.rootPath ??
        options.expectedTarget?.rootPath ??
        options.defaultRootPath,
    ),
    kind: 'interactive',
  });
  assertCanonicalSetupTarget(options.expectedTarget, capability.rootId, capability.canonicalPath);
  const recoveryDeps: RuntimeHostLifecycleTransactionDeps = {
    convergeOperator: (currentConfig, desiredConfig) =>
      deps.convergeOperator(currentConfig, desiredConfig),
    verifyOperator: deps.verifyOperator,
    resolveProvider: deps.resolveLifecycleProvider,
    ...(legacyConfig && legacyBackend
      ? legacyMigrationDeps(legacyConfig, legacyBackend, legacyServiceId, options.clientDataRoot)
      : {}),
  };
  const recovered = await resolveRecoverableRuntimeHostManagedDeployment(
    capability.rootId,
    recoveryDeps,
    {
      ...(legacyBackend ? { retirementSupervisor: legacyBackend } : {}),
      ...(legacyBackend ? { activatePrevious: () => legacyBackend.start() } : {}),
      ...(options.expectedTarget ? { expectedTarget: options.expectedTarget } : {}),
    },
  );
  const current = recovered.kind === 'active' ? recovered.config : undefined;
  const legacyToMigrate = current ? null : legacyConfig;
  if (current && legacyBackend) await assertLegacyArtifactsAbsent(legacyBackend);
  if (legacyToMigrate && legacyStatus) {
    await assertCompatibleExistingVersion(legacyStatus, options.version);
  }
  assertExpectedDeploymentGeneration(options.expectedTarget, current);
  const resolvedPackage = await resolveRuntimeHostSetupPackage(options, deps);
  const { candidate } = resolvedPackage;
  const serviceId = capability.rootId;
  const deploymentRoot =
    current?.deploymentRoot ?? resolveRuntimeHostManagedDeploymentRoot(serviceId);
  const packageChanged = current !== undefined && !sameExactPackage(current, candidate);
  if (current && packageChanged && !options.updateExisting) {
    throw new RuntimeHostSetupError(
      'version_change_requires_update',
      `Runtime Host ${current.launch.package.version} is already installed; changing its exact package requires the update workflow`,
    );
  }
  const draft: RuntimeHostManagedDeploymentConfig = {
    schemaVersion: 1,
    state: 'active',
    deploymentId: current?.deploymentId ?? randomUUID(),
    configRevision: current ? current.configRevision + 1 : 1,
    deploymentRoot,
    root: { path: capability.canonicalPath, id: capability.rootId },
    projectDirectoryRoots: options.projectDirectoryRoots?.map(({ label, path }) => ({
      label,
      path: resolve(path),
    })) ??
      current?.projectDirectoryRoots ?? [{ label: '~', path: resolve(homedir()) }],
    launch: {
      kind: 'exact_package',
      nodePath: current?.launch.nodePath ?? process.execPath,
      package: {
        kind: 'npm_registry',
        version: candidate.version,
        integrity: candidate.integrity,
      },
    },
    listeners: {
      localIpc: true,
      websocket: {
        host: '127.0.0.1',
        port: options.websocketPort ?? 0,
        path: options.websocketPath ?? current?.listeners.websocket?.path ?? '/runtime-host',
      },
      ...(current?.listeners.directPeer
        ? { directPeer: { ...current.listeners.directPeer, enabled: false } }
        : {}),
    },
    lifecycle: { mode: 'on_demand', availability: 'activation' },
    reconciliation: { trigger: 'activation' },
  };
  const reuseCurrent =
    current?.lifecycle.mode === 'on_demand' && sameDesiredManagedDeployment(current, draft);
  const config = reuseCurrent ? current : draft;
  let activation: Awaited<ReturnType<typeof activateRuntimeHostManagedDeployment>> | undefined;
  const lifecycleDeps: RuntimeHostLifecycleTransactionDeps = {
    convergeOperator: (currentConfig, desiredConfig) =>
      deps.convergeOperator(currentConfig, desiredConfig),
    verifyOperator: deps.verifyOperator,
    resolveProvider: deps.resolveLifecycleProvider,
    ...(legacyToMigrate && legacyBackend
      ? legacyMigrationDeps(legacyToMigrate, legacyBackend, legacyServiceId, options.clientDataRoot)
      : {}),
  };
  const deployedConfig = await resolvedPackage.use(async (packageRoot) => {
    let committed = false;
    const created = !current;
    let deployment: Awaited<ReturnType<typeof deps.prepareDeployment>> | undefined;
    try {
      emit({ kind: 'progress', phase: 'installing_package' });
      deployment =
        current && !packageChanged
          ? await deps.openDeployment({
              serviceId,
              clientDataRoot: options.clientDataRoot,
              deploymentRoot,
              cliPath: resolveRuntimeHostManagedPackageCliPath(
                deploymentRoot,
                candidate.version,
                candidate.integrity,
              ),
              version: candidate.version,
            })
          : await deps.prepareDeployment({
              serviceId,
              clientDataRoot: options.clientDataRoot,
              sourcePackageRoot: packageRoot,
              version: candidate.version,
              packageIntegrity: candidate.integrity,
              ...(current ? { deploymentRoot } : {}),
            });
      const desiredConfig: RuntimeHostManagedDeploymentConfig = current
        ? config
        : { ...config, deploymentRoot: deployment.root };
      emit({ kind: 'progress', phase: 'installing_service' });
      if (legacyToMigrate && legacyBackend) {
        await legacyBackend.verifyDeployment(legacyToMigrate, {
          acceptLegacyConfigLaunch: true,
        });
      }
      if (reuseCurrent) {
        await deps.convergeOperator(current, current);
        await deps.verifyOperator(current);
      } else {
        const replacement = await deps.replaceLifecycle({
          operation: legacyToMigrate
            ? 'legacy_migration'
            : packageChanged
              ? 'update'
              : current
                ? isDeepStrictEqual(current.lifecycle, config.lifecycle)
                  ? 'configure'
                  : 'lifecycle_change'
                : 'install',
          ...(current ? { current } : {}),
          desired: desiredConfig,
          ...(legacyToMigrate && legacyBackend ? { retirementSupervisor: legacyBackend } : {}),
          ...(legacyToMigrate && legacyBackend
            ? { activatePrevious: () => legacyBackend.start() }
            : {}),
          activateDesired: async () => {
            await deps.activateDesired({ rootId: capability.rootId });
          },
          allowInterruptActiveTasks: options.allowInterruptActiveTasks === true,
          deps: lifecycleDeps,
        });
        if (replacement.kind === 'active_tasks') {
          throw new RuntimeHostSetupError(
            'active_tasks',
            'Runtime Host setup is waiting for active work to finish',
          );
        }
      }
      committed = true;
      await deps.prunePackages(
        (await resolveRuntimeHostManagedDeployment(capability.rootId)).config,
      );
      return desiredConfig;
    } catch (error) {
      if (!committed && canDiscardRuntimeHostLifecycleDesiredArtifacts(error)) {
        if (packageChanged && deployment) await deployment.rollback().catch(() => undefined);
        else if (created) {
          await removeRuntimeHostManagedDeployment(deploymentRoot, serviceId).catch(
            () => undefined,
          );
        }
      }
      throw error;
    }
  });
  activation = await deps.activateManaged({ rootId: capability.rootId });
  if (legacyConfig) {
    await removeRuntimeHostServiceFile(
      resolveRuntimeHostManagedServiceConfigPath(options.clientDataRoot),
      'legacy service config',
    );
    if (
      legacyConfig.managedDeploymentRoot &&
      resolve(legacyConfig.managedDeploymentRoot) !== resolve(config.deploymentRoot)
    ) {
      await removeRuntimeHostManagedDeployment(legacyConfig.managedDeploymentRoot, legacyServiceId);
    }
  }
  await pairAndVerifyRuntimeHostSetup(
    options,
    {
      serviceId,
      deploymentId: deployedConfig.deploymentId,
      operator: runtimeHostManagedOperatorCommand(
        deployedConfig,
        process.platform === 'win32' ? 'win32' : 'posix',
      ),
      rootPath: capability.canonicalPath,
      endpoint: websocketUrl({
        host: activation.endpoint.host,
        port: activation.endpoint.port,
        path: activation.endpoint.websocketPath,
      }),
    },
    deps,
    emit,
  );
}

function legacyMigrationDeps(
  config: RuntimeHostManagedServiceConfig,
  backend: RuntimeHostServiceBackend,
  legacyServiceId: string,
  clientDataRoot: string,
): Pick<RuntimeHostLifecycleTransactionDeps, 'uninstallLegacy' | 'restoreLegacy'> {
  return {
    uninstallLegacy: async (transition) => {
      await projectLegacyUpdatePolicy(config, legacyServiceId, transition.to ?? transition.from);
      await backend.uninstall();
    },
    restoreLegacy: async (transition) => {
      await removeProjectedLegacyUpdatePolicy(config, transition.to ?? transition.from);
      if (config.managedDeploymentRoot) {
        await restoreRuntimeHostLegacyManagedOperator({
          deploymentRoot: config.managedDeploymentRoot,
          nodePath: config.launch.nodePath,
          cliPath: config.launch.cliPath,
          clientDataRoot,
          serviceId: legacyServiceId,
        });
      }
      const restoration = await backend.stageDeployment();
      await restoration.apply(config, false);
    },
  };
}

async function projectLegacyUpdatePolicy(
  config: RuntimeHostManagedServiceConfig,
  legacyServiceId: string,
  desired: RuntimeHostManagedDeploymentConfig | null,
): Promise<void> {
  if (!config.managedDeploymentRoot || !desired) return;
  const record = await readRuntimeHostManagedUpdatePolicy(config.managedDeploymentRoot);
  if (record) {
    if (
      record.target.serviceId !== legacyServiceId ||
      record.target.rootId !== desired.root.id ||
      resolve(record.target.rootPath) !== resolve(desired.root.path)
    ) {
      throw new RuntimeHostSetupError(
        'target_mismatch',
        'The legacy automatic update policy does not match the Runtime Host migration target',
      );
    }
    await writeRuntimeHostManagedUpdatePolicy(desired.deploymentRoot, {
      ...record,
      target: {
        serviceId: desired.root.id,
        rootId: desired.root.id,
        rootPath: desired.root.path,
        deploymentId: desired.deploymentId,
      },
    });
  } else {
    await writeRuntimeHostManagedUpdatePolicy(desired.deploymentRoot, null);
  }
}

async function removeProjectedLegacyUpdatePolicy(
  config: RuntimeHostManagedServiceConfig,
  desired: RuntimeHostManagedDeploymentConfig | null,
): Promise<void> {
  if (
    config.managedDeploymentRoot &&
    desired &&
    resolve(config.managedDeploymentRoot) !== resolve(desired.deploymentRoot)
  ) {
    await writeRuntimeHostManagedUpdatePolicy(desired.deploymentRoot, null);
  }
}

function legacyManagedTarget(
  target: RuntimeHostManagedServiceTarget,
  legacyServiceId: string,
): RuntimeHostManagedServiceTarget {
  return {
    serviceId: legacyServiceId,
    rootPath: target.rootPath,
    rootId: target.rootId,
  };
}

function assertCanonicalSetupTarget(
  target: RuntimeHostManagedServiceTarget | undefined,
  rootId: string,
  rootPath: string,
): void {
  if (
    target &&
    (target.serviceId !== rootId || target.rootId !== rootId || target.rootPath !== rootPath)
  ) {
    throw new RuntimeHostSetupError(
      'target_mismatch',
      'The managed Runtime Host does not match the expected deployment identity',
    );
  }
}

function assertExpectedDeploymentGeneration(
  target: RuntimeHostManagedServiceTarget | undefined,
  current: RuntimeHostManagedDeploymentConfig | undefined,
): void {
  if (
    target?.deploymentId !== undefined &&
    (!current || target.deploymentId !== current.deploymentId)
  ) {
    throw new RuntimeHostSetupError(
      'target_mismatch',
      'The managed Runtime Host deployment generation changed before setup',
    );
  }
}

async function assertLegacyArtifactsAbsent(backend: RuntimeHostServiceBackend): Promise<void> {
  const status = await backend.status();
  if (status.installed || status.enabled || status.active) {
    throw new RuntimeHostSetupError(
      'lifecycle_owner_exists',
      'The canonical deployment is active but its legacy lifecycle artifact can still start',
    );
  }
}

function sameExactPackage(
  config: RuntimeHostManagedDeploymentConfig,
  candidate: { readonly version: string; readonly integrity: string },
): boolean {
  return (
    config.launch.package.version === candidate.version &&
    config.launch.package.integrity === candidate.integrity
  );
}

async function pairAndVerifyRuntimeHostSetup(
  options: RuntimeHostSetupCliOptions,
  target: {
    readonly serviceId: string;
    readonly deploymentId: string;
    readonly operator: RuntimeHostNodeOperatorCommand;
    readonly rootPath: string;
    readonly endpoint: string;
    readonly directPeer?: {
      readonly peerId: string;
      readonly routeHints: readonly string[];
      readonly coordinationRelays: readonly string[];
    };
  },
  deps: RuntimeHostSetupDeps,
  emit: SetupEmitter,
): Promise<void> {
  emit({ kind: 'progress', phase: 'pairing_client' });
  let paired: Awaited<ReturnType<typeof prepareRuntimeHostAccessCredential>>;
  try {
    const pairCredential = options.deferPairingCommit
      ? deps.prepareCredential
      : deps.replaceCredential;
    const credentialInput = {
      rootPath: target.rootPath,
      principalKind: 'remote_owner' as const,
      principalId: options.principalId,
      operationGrants: [],
      canPublishClientCapabilities: false,
      canUseHostPaths: false,
      preset: options.preset,
      ...(options.bindPairingToClient ? { bindClientInstance: true } : {}),
    };
    const deadline = Date.now() + RUNTIME_HOST_READY_TIMEOUT_MS;
    while (true) {
      try {
        paired = await pairCredential(credentialInput);
        break;
      } catch (error) {
        if (!isTransientPairingAvailabilityError(error) || Date.now() >= deadline) {
          throw error;
        }
        await new Promise<void>((resolveWait) =>
          setTimeout(resolveWait, Math.min(PAIRING_AVAILABILITY_POLL_MS, deadline - Date.now())),
        );
      }
    }
  } catch (error) {
    const reason =
      error instanceof RuntimeHostAccessUnavailableError
        ? error.message
        : generalizedErrorMessage(error, 'Runtime Host access service is unavailable');
    throw new RuntimeHostSetupError(
      'pairing_failed',
      `Runtime Host could not pair the requested Client identity: ${reason}`,
      { cause: error },
    );
  }

  emit({ kind: 'progress', phase: 'verifying_connection' });
  try {
    await deps.verifyCredential({
      endpoint: target.endpoint,
      rootId: paired.rootId,
      credential: paired.credential,
    });
    emit({
      kind: 'complete',
      version: options.version,
      serviceId: target.serviceId,
      deploymentId: target.deploymentId,
      operator: target.operator,
      rootPath: target.rootPath,
      rootId: paired.rootId,
      endpoint: target.endpoint,
      credentialId: paired.credentialId,
      credential: paired.credential,
      ...(target.directPeer
        ? {
            directPeer: {
              peerId: target.directPeer.peerId,
              routeHints: [...target.directPeer.routeHints],
              coordinationRelays: [...target.directPeer.coordinationRelays],
            },
          }
        : {}),
    });
  } catch (error) {
    if (options.deferPairingCommit) {
      try {
        await deps.revokeCredential({
          rootPath: target.rootPath,
          credentialId: paired.credentialId,
        });
      } catch (rollbackError) {
        throw new AggregateError(
          [error, rollbackError],
          'Runtime Host pairing failed and its candidate credential could not be revoked',
        );
      }
    }
    throw error;
  }
}

function isTransientPairingAvailabilityError(error: unknown): boolean {
  return (
    error instanceof RuntimeHostAccessUnavailableError ||
    (error instanceof RuntimeHostOperationError &&
      (error.code === 'host_not_ready' || error.code === 'host_draining'))
  );
}

async function assertCompatibleExistingVersion(
  status: RuntimeHostManagedServiceResult,
  version: string,
): Promise<void> {
  if (!status.service.config) {
    if (!status.service.installed) return;
    throw new RuntimeHostSetupError(
      'existing_installation_unknown',
      'The installed Runtime Host configuration is unavailable; repair it before setup',
    );
  }
  const existingVersion = status.service.installedVersion;
  if (!existingVersion) {
    throw new RuntimeHostSetupError(
      'existing_installation_unknown',
      'The installed Runtime Host version could not be identified; repair it before setup',
    );
  }
  if (
    existingVersion !== version &&
    !(
      isRuntimeHostDevelopmentPackageVersion(existingVersion) &&
      isRuntimeHostDevelopmentPackageVersion(version)
    )
  ) {
    throw new RuntimeHostSetupError(
      'version_change_requires_update',
      `Runtime Host ${String(existingVersion)} is already installed; changing to ${version} requires the update workflow`,
    );
  }
}

async function verifyRuntimeHostSetupCredential(input: {
  readonly endpoint: string;
  readonly rootId: string;
  readonly credential: string;
}): Promise<void> {
  const result = await connectRemoteRuntimeHost({
    url: input.endpoint,
    credential: input.credential,
    expectedRootId: input.rootId,
    compositionId: INTERACTIVE_RUNTIME_HOST_COMPOSITION_ID,
    protocol: {
      min: RUNTIME_HOST_PROTOCOL_VERSION,
      max: RUNTIME_HOST_PROTOCOL_VERSION,
    },
  });
  if (result.kind !== 'connected') {
    throw new RuntimeHostSetupError(
      'verification_failed',
      `The paired Runtime Host connection could not be verified (${result.kind})`,
    );
  }
  try {
    const status = await result.connection.status();
    if (status.state !== 'ready') {
      throw new RuntimeHostSetupError(
        'verification_failed',
        `The paired Runtime Host is ${status.state}`,
      );
    }
  } finally {
    await result.connection.close();
  }
}

type SetupEmitter = (
  frame:
    | Omit<Extract<RuntimeHostSetupFrame, { kind: 'progress' }>, 'schemaVersion' | 'sequence'>
    | Omit<Extract<RuntimeHostSetupFrame, { kind: 'complete' }>, 'schemaVersion' | 'sequence'>
    | Omit<
        Extract<RuntimeHostSetupFrame, { kind: 'existing_environment' }>,
        'schemaVersion' | 'sequence'
      >
    | Omit<Extract<RuntimeHostSetupFrame, { kind: 'error' }>, 'schemaVersion' | 'sequence'>,
) => void;

function createEmitter(json: boolean, deps: RuntimeHostSetupDeps): SetupEmitter {
  let sequence = 0;
  return (input) => {
    const frame = {
      schemaVersion: 1,
      sequence: sequence++,
      ...input,
    } as RuntimeHostSetupFrame;
    if (json) {
      deps.writeOutput(encodeRuntimeHostSetupFrame(frame));
      return;
    }
    if (frame.kind === 'progress') {
      deps.writeOutput(`${humanPhase(frame.phase)}\n`);
    } else if (frame.kind === 'complete' || frame.kind === 'existing_environment') {
      deps.writeOutput(`${JSON.stringify(frame, null, 2)}\n`);
    } else {
      deps.writeError(`${frame.error.message}\n`);
    }
  };
}

function setupFailure(error: unknown): { code: string; message: string } {
  let code = 'internal_setup_failure';
  let message = 'Runtime Host setup failed';
  if (
    error instanceof RuntimeHostSetupError ||
    error instanceof RuntimeHostServiceManagerError ||
    error instanceof RuntimeHostManagedDeploymentError ||
    error instanceof RuntimeHostDeploymentAuthorityError ||
    error instanceof RuntimeHostUpdateDiscoveryError ||
    error instanceof RuntimeHostUpdatePackageError ||
    error instanceof RuntimeHostLifecycleTransactionError
  ) {
    code = error.code;
    message = error.message;
  }
  return {
    code: truncateUtf8(code, RUNTIME_HOST_SETUP_ERROR_CODE_MAX_BYTES) || 'internal_setup_failure',
    message:
      truncateUtf8(message, RUNTIME_HOST_SETUP_ERROR_MESSAGE_MAX_BYTES) ||
      'Runtime Host setup failed',
  };
}

function websocketUrl(input: {
  readonly host: string;
  readonly port: number;
  readonly path: string;
}) {
  return `ws://${input.host}:${input.port}${input.path}`;
}

function humanPhase(phase: RuntimeHostSetupPhase): string {
  switch (phase) {
    case 'checking_environment':
      return 'Checking the remote environment...';
    case 'installing_package':
      return 'Installing the managed Maka package...';
    case 'installing_service':
      return 'Installing the Runtime Host deployment...';
    case 'pairing_client':
      return 'Pairing the Client...';
    case 'verifying_connection':
      return 'Verifying the Runtime Host connection...';
  }
}
