import { IllegalStateError, type Workflow } from '@temporalio/common';
import type { Activator } from './internals';
import type { WorkflowInterceptorsFactory } from './interceptors';

declare global {
  // The __TEMPORAL__ object will be assigned by Webpack to the exports of the entrypoint module
  // file dynamically generated by the bundler (see workflow/bundler.ts#genEntrypoint()).
  //
  // FIXME: Rename to lowercase syntax before 1.15.0. I preserved the uppercase name for backward
  // compatibility with bundles generated by 1.14.0. We generally do not guarantee compatibility of
  // bundles with different versions of the SDK, but in this specific case, there's really no
  // user-side value in renaming this, so making a breaking change for that would not be justified.
  //

  var __TEMPORAL__: {
    api: typeof import('./worker-interface.ts');
    preloadModules?: () => void;
    importWorkflows: () => Record<string, Workflow>;
    importInterceptors: () => [{ interceptors: WorkflowInterceptorsFactory }];
  };

  // Destructors to be called when the shared sandbox is destroyed.

  var __temporal_globalSandboxDestructors: (() => void)[] | undefined;

  // FIXME: Rename to lowercase syntax before 1.15.0.

  var __TEMPORAL_ACTIVATOR__: Activator | undefined;
}

export function setActivator(activator: Activator | undefined): void {
  globalThis.__TEMPORAL_ACTIVATOR__ = activator;
}

export function maybeGetActivator(): Activator | undefined {
  return globalThis.__TEMPORAL_ACTIVATOR__;
}

export function assertInWorkflowContext(uninitializedErrorMessage: string): Activator {
  const activator = maybeGetActivator();
  if (activator == null) throw new IllegalStateError(uninitializedErrorMessage);
  return activator;
}

// This is really just an alias for `assertInWorkflowContext` with a default error message,
// because that name better conveys the intent in some very common use cases.
export const getActivator = assertInWorkflowContext.bind(null, 'Workflow uninitialized');
