/**
 * @license
 * Copyright 2022 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import {
  SyntaxWorkerRequest,
  SyntaxWorkerInit,
  SyntaxWorkerResult,
  SyntaxWorkerMessageType,
  SyntaxLayerLine,
} from '../../types/syntax-worker-api';
import {prependOrigin} from '../../utils/url-util';
import {createWorker} from '../../utils/worker-util';
import {ReportingService} from '../gr-reporting/gr-reporting';
import {Finalizable} from '../registry';

const hljsLibUrl = `${
  window.STATIC_RESOURCE_PATH ?? ''
}/bower_components/highlightjs/highlight.min.js`;

const syntaxWorkerUrl = `${
  window.STATIC_RESOURCE_PATH ?? ''
}/workers/syntax-worker.js`;

/**
 * It is unlikely that a pool size greater than 3 will gain anything, because
 * the app also needs the resources to process the results.
 */
const WORKER_POOL_SIZE = 3;

/**
 * Safe guard for not killing the browser.
 */
export const CODE_MAX_LINES = 20 * 1000;

/**
 * Safe guard for not killing the browser. Maximum in number of chars.
 */
const CODE_MAX_LENGTH = 25 * CODE_MAX_LINES;

/**
 * Service for syntax highlighting. Maintains some HighlightJS workers doing
 * their job in the background.
 */
export class HighlightService implements Finalizable {
  // visible for testing
  poolIdle: Set<Worker> = new Set();

  // visible for testing
  poolBusy: Set<Worker> = new Set();

  // visible for testing
  /** Queue for waiting that a worker becomes available. */
  queueForWorker: Array<() => void> = [];

  // visible for testing
  /** Queue for waiting on the results of a worker. */
  queueForResult: Map<Worker, (r: SyntaxLayerLine[]) => void> = new Map();

  constructor(readonly reporting: ReportingService) {
    for (let i = 0; i < WORKER_POOL_SIZE; i++) {
      this.addWorker();
    }
  }

  /** Allows tests to produce fake workers. */
  protected createWorker() {
    return createWorker(prependOrigin(syntaxWorkerUrl));
  }

  /** Creates, initializes and then moves a worker to the idle pool. */
  private addWorker() {
    const worker = this.createWorker();
    // Will move to the idle pool after being initialized.
    this.poolBusy.add(worker);
    worker.onmessage = (e: MessageEvent<SyntaxWorkerResult>) => {
      this.handleResult(worker, e.data);
    };
    const initMsg: SyntaxWorkerInit = {
      type: SyntaxWorkerMessageType.INIT,
      url: prependOrigin(hljsLibUrl),
    };
    worker.postMessage(initMsg);
  }

  private moveIdleToBusy() {
    const worker = this.poolIdle.values().next().value;
    this.poolIdle.delete(worker);
    this.poolBusy.add(worker);
    return worker;
  }

  private moveBusyToIdle(worker: Worker) {
    this.poolBusy.delete(worker);
    this.poolIdle.add(worker);
    const resolver = this.queueForWorker.shift();
    if (resolver) resolver();
  }

  /**
   * If there is worker in the idle pool, then return it. Otherwise wait for a
   * worker to become a available.
   */
  private async requestWorker(): Promise<Worker> {
    if (this.poolIdle.size > 0) {
      const worker = this.moveIdleToBusy();
      return Promise.resolve(worker);
    }
    await new Promise<void>(r => this.queueForWorker.push(r));
    return this.requestWorker();
  }

  /**
   * A worker is done with its job. Move it back to the idle pool and notify the
   * resolver that is waiting for the results.
   */
  private handleResult(worker: Worker, result: SyntaxWorkerResult) {
    this.moveBusyToIdle(worker);
    if (result.error) {
      this.reporting.error(new Error(`syntax worker failed: ${result.error}`));
    }
    const resolver = this.queueForResult.get(worker);
    this.queueForResult.delete(worker);
    if (resolver) resolver(result.ranges ?? []);
  }

  async highlight(
    language?: string,
    code?: string
  ): Promise<SyntaxLayerLine[]> {
    if (!language || !code) return [];
    if (code.length > CODE_MAX_LENGTH) return [];
    const worker = await this.requestWorker();
    const message: SyntaxWorkerRequest = {
      type: SyntaxWorkerMessageType.REQUEST,
      language,
      code,
    };
    const promise = new Promise<SyntaxLayerLine[]>(r => {
      this.queueForResult.set(worker, r);
    });
    worker.postMessage(message);
    return await promise;
  }

  finalize() {
    for (const worker of this.poolIdle) {
      worker.terminate();
    }
    this.poolIdle.clear();
    for (const worker of this.poolBusy) {
      worker.terminate();
    }
    this.poolBusy.clear();
    this.queueForResult.clear();
    this.queueForWorker.length = 0;
  }
}
