/*!
 * @license
 * Copyright 2021 The Go Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file.
 */

// This file implements the playground implementation of the documentation
// page. The playground involves a "play" button that allows you to open up
// a new link to play.golang.org using the example code.

// The CSS is in static/frontend/unit/main/_doc.css

/**
 * CSS classes used by PlaygroundExampleController
 */
const PlayExampleClassName = {
  PLAY_HREF: '.js-exampleHref',
  PLAY_CONTAINER: '.js-exampleContainer',
  EXAMPLE_INPUT: '.Documentation-exampleCode',
  EXAMPLE_OUTPUT: '.Documentation-exampleOutput',
  EXAMPLE_ERROR: '.Documentation-exampleError',
  PLAY_BUTTON: '.Documentation-examplePlayButton',
  SHARE_BUTTON: '.Documentation-exampleShareButton',
  FORMAT_BUTTON: '.Documentation-exampleFormatButton',
  RUN_BUTTON: '.Documentation-exampleRunButton',
};

/**
 * This controller enables playground examples to expand their dropdown or
 * generate shareable Go Playground URLs.
 */
export class PlaygroundExampleController {
  /**
   * The anchor tag used to identify the container with an example href.
   * There is only one in an example container div.
   */
  private readonly anchorEl: HTMLAnchorElement | null;

  /**
   * The error element
   */
  private readonly errorEl: Element | null;

  /**
   * Buttons that redirect to an example's playground, this element
   * only exists in executable examples.
   */
  private readonly playButtonEl: Element | null;
  private readonly shareButtonEl: Element | null;

  /**
   * Button that formats the code in an example's playground.
   */
  private readonly formatButtonEl: Element | null;

  /**
   * Button that runs the code in an example's playground, this element
   * only exists in executable examples.
   */
  private readonly runButtonEl: Element | null;

  /**
   * The executable code of an example.
   */
  private readonly inputEl: HTMLTextAreaElement | null;

  /**
   * The output of the given example code. This only exists if the
   * author of the package provides an output for this example.
   */
  private readonly outputEl: Element | null;

  /**
   * @param exampleEl The div that contains playground content for the given example.
   */
  constructor(private readonly exampleEl: HTMLDetailsElement) {
    this.exampleEl = exampleEl;
    this.anchorEl = exampleEl.querySelector('a');
    this.errorEl = exampleEl.querySelector(PlayExampleClassName.EXAMPLE_ERROR);
    this.playButtonEl = exampleEl.querySelector(PlayExampleClassName.PLAY_BUTTON);
    this.shareButtonEl = exampleEl.querySelector(PlayExampleClassName.SHARE_BUTTON);
    this.formatButtonEl = exampleEl.querySelector(PlayExampleClassName.FORMAT_BUTTON);
    this.runButtonEl = exampleEl.querySelector(PlayExampleClassName.RUN_BUTTON);
    this.inputEl = this.makeTextArea(exampleEl.querySelector(PlayExampleClassName.EXAMPLE_INPUT));
    this.outputEl = exampleEl.querySelector(PlayExampleClassName.EXAMPLE_OUTPUT);

    // This is legacy listener to be replaced the listener for shareButtonEl.
    this.playButtonEl?.addEventListener('click', () => this.handleShareButtonClick());
    this.shareButtonEl?.addEventListener('click', () => this.handleShareButtonClick());
    this.formatButtonEl?.addEventListener('click', () => this.handleFormatButtonClick());
    this.runButtonEl?.addEventListener('click', () => this.handleRunButtonClick());

    if (!this.inputEl) return;

    this.resize();
    this.inputEl.addEventListener('keyup', () => this.resize());
    this.inputEl.addEventListener('keydown', e => this.onKeydown(e));
  }

  /**
   * Replace the pre element with a textarea. The examples are initially rendered
   * as pre elements so they're fully visible when JS is disabled.
   */
  makeTextArea(el: Element | null): HTMLTextAreaElement {
    const t = document.createElement('textarea');
    t.classList.add('Documentation-exampleCode', 'code');
    t.spellcheck = false;
    t.value = el?.textContent ?? '';
    el?.parentElement?.replaceChild(t, el);
    return t;
  }

  /**
   * Retrieve the hash value of the anchor element.
   */
  getAnchorHash(): string | undefined {
    return this.anchorEl?.hash;
  }

  /**
   * Expands the current playground example.
   */
  expand(): void {
    this.exampleEl.open = true;
  }

  /**
   * Resizes the input element to accommodate the amount of text present.
   */
  private resize(): void {
    if (this.inputEl?.value) {
      const numLineBreaks = (this.inputEl.value.match(/\n/g) || []).length;
      // min-height + lines x line-height + padding + border
      this.inputEl.style.height = `${(20 + numLineBreaks * 20 + 12 + 2) / 16}rem`;
    }
  }

  /**
   * Handler to override keyboard behavior in the playground's
   * textarea element.
   *
   * Tab key inserts tabs into the example playground instead of
   * switching to the next interactive element.
   * @param e input element keyboard event.
   */
  private onKeydown(e: KeyboardEvent) {
    if (e.key === 'Tab') {
      document.execCommand('insertText', false, '\t');
      e.preventDefault();
    }
  }

  /**
   * Changes the text of the example's input box.
   */
  private setInputText(output: string) {
    if (this.inputEl) {
      this.inputEl.value = output;
    }
  }

  /**
   * Changes the text of the example's output box.
   */
  private setOutputText(output: string) {
    if (this.outputEl) {
      this.outputEl.textContent = output;
    }
  }

  /**
   * Appends to the text of the example's output box.
   */
  private appendToOutputText(output: string) {
    if (this.outputEl) {
      this.outputEl.textContent += output;
    }
  }

  private setOutputHTML(output: string) {
    if (this.outputEl) {
      this.outputEl.innerHTML = output;
    }
  }

  /**
   * Sets the error message text and overwrites
   * output box to indicate a failed response.
   */
  private setErrorText(err: string) {
    if (this.errorEl) {
      this.errorEl.textContent = err;
    }
    this.setOutputText('An error has occurred…');
  }

  private getCodeWithModFile(): string {
    let codeWithModFile = this.inputEl?.value ?? '';
    const moduleVars = document.querySelector<HTMLDivElement>('.js-playgroundVars')?.dataset ?? {};
    if (moduleVars.modulepath !== 'std') {
      codeWithModFile = codeWithModFile.concat(`
-- go.mod --
module play.ground

require ${moduleVars.modulepath} ${moduleVars.version}
`);
    }

    return codeWithModFile;
  }

  /**
   * Opens a new window to play.golang.org using the
   * example snippet's code in the playground.
   */
  private handleShareButtonClick() {
    const PLAYGROUND_BASE_URL = 'https://play.golang.org/p/';

    this.setOutputText('Waiting for remote server…');

    fetch('/play/share', {
      method: 'POST',
      body: this.getCodeWithModFile(),
    })
      .then(res => res.text())
      .then(shareId => {
        const href = PLAYGROUND_BASE_URL + shareId;
        this.setOutputHTML(`<a href="${href}">${href}</a>`);
        window.open(href);
      })
      .catch(err => {
        this.setErrorText(err);
      });
  }

  /**
   * Runs gofmt on the example snippet in the playground.
   */
  private handleFormatButtonClick() {
    this.setOutputText('Waiting for remote server…');
    const body = new FormData();
    body.append('body', this.inputEl?.value ?? '');

    fetch('/play/fmt', {
      method: 'POST',
      body: body,
    })
      .then(res => res.json())
      .then(({ Body, Error }) => {
        this.setOutputText(Error || 'Done.');
        if (Body) {
          this.setInputText(Body);
          this.resize();
        }
      })
      .catch(err => {
        this.setErrorText(err);
      });
  }

  /**
   * Runs the code snippet in the example playground.
   */
  private handleRunButtonClick() {
    this.setOutputText('Waiting for remote server…');

    fetch('/play/compile', {
      method: 'POST',
      body: JSON.stringify({ body: this.getCodeWithModFile(), version: 2 }),
    })
      .then(res => res.json())
      .then(async ({ Events, Errors }) => {
        this.setOutputText(Errors || '');
        for (const e of Events || []) {
          this.appendToOutputText(e.Message);
          await new Promise(resolve => setTimeout(resolve, e.Delay / 1000000));
        }
      })
      .catch(err => {
        this.setErrorText(err);
      });
  }
}

export function initPlaygrounds(): void {
  const exampleHashRegex = location.hash.match(/^#(example-.*)$/);
  if (exampleHashRegex) {
    const exampleHashEl = document.getElementById(exampleHashRegex[1]) as HTMLDetailsElement;
    if (exampleHashEl) {
      exampleHashEl.open = true;
    }
  }

  // We use a spread operator to convert a nodelist into an array of elements.
  const exampleHrefs = [
    ...document.querySelectorAll<HTMLAnchorElement>(PlayExampleClassName.PLAY_HREF),
  ];

  /**
   * Sometimes exampleHrefs and playContainers are in different order, so we
   * find an exampleHref from a common hash.
   * @param playContainer - playground container
   */
  const findExampleHash = (playContainer: PlaygroundExampleController) =>
    exampleHrefs.find(ex => {
      return ex.hash === playContainer.getAnchorHash();
    });

  for (const el of document.querySelectorAll(PlayExampleClassName.PLAY_CONTAINER)) {
    // There should be the same amount of hrefs referencing examples as example containers.
    const playContainer = new PlaygroundExampleController(el as HTMLDetailsElement);
    const exampleHref = findExampleHash(playContainer);
    if (exampleHref) {
      exampleHref.addEventListener('click', () => {
        playContainer.expand();
      });
    } else {
      console.warn('example href not found');
    }
  }
}
