import { Thread } from '../Thread.mjs';
import { portToMessageTarget } from './ThreadMessagePort.mjs';

/**
 * Creates a thread from a `BroadcastChannel` instance in the browser.
 *
 * @see https://developer.mozilla.org/en-US/docs/Web/API/BroadcastChannel
 *
 * @example
 * import {ThreadBroadcastChannel} from '@quilted/threads';
 *
 * const channel = new BroadcastChannel('my-channel');;
 * const thread = new ThreadBroadcastChannel(channel);
 * await thread.imports.sendMessage('Hello world!');
 */
class ThreadBroadcastChannel extends Thread {
  /**
   * Starts a thread wrapped around a `BroadcastChannel` object, and returns the imports
   * of the thread.
   *
   * @example
   * ```ts
   * import {ThreadBroadcastChannel} from '@quilted/threads';
   *
   * const channel = new BroadcastChannel('my-channel');
   * const {getMessage} = ThreadBroadcastChannel.import(channel);
   * const message = await getMessage(); // 'Hello, world!'
   *
   * // In another context (tab, window, etc.):
   *
   * import {ThreadBroadcastChannel} from '@quilted/threads';
   *
   * const channel = new BroadcastChannel('my-channel');
   * ThreadBroadcastChannel.export(channel, {
   *   async getMessage() {
   *     return 'Hello, world!';
   *   },
   * });
   * ```
   */
  static import(channel, options) {
    return new ThreadBroadcastChannel(channel, options).imports;
  }

  /**
   * Starts a thread wrapped around a `BroadcastChannel` object, providing the second
   * argument as the exports of the thread.
   *
   * @example
   * ```ts
   * import {ThreadBroadcastChannel} from '@quilted/threads';
   *
   * const channel = new BroadcastChannel('my-channel');
   *
   * ThreadBroadcastChannel.export(channel, {
   *   async getMessage() {
   *     return 'Hello, world!';
   *   },
   * });
   *
   * // In another context (tab, window, etc.):
   *
   * import {ThreadBroadcastChannel} from '@quilted/threads';
   *
   * const channel = new BroadcastChannel('my-channel');
   * const {getMessage} = ThreadBroadcastChannel.import(channel);
   * const message = await getMessage(); // 'Hello, world!'
   * ```
   */
  static export(channel, exports, options) {
    new ThreadBroadcastChannel(channel, {
      ...options,
      exports
    });
  }
  constructor(channel, options) {
    super(portToMessageTarget(channel), options);
    this.channel = channel;
  }
}

export { ThreadBroadcastChannel };
