/*!
 * @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;
    }
  }

  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…');
  }

  /**
   * 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.inputEl?.value,
    })
      .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…');

    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}
`);
    }
    fetch('/play/compile', {
      method: 'POST',
      body: JSON.stringify({ body: codeWithModFile, version: 2 }),
    })
      .then(res => res.json())
      .then(async ({ Events, Errors }) => {
        this.setOutputText(Errors || '');
        for (const e of Events || []) {
          this.setOutputText(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');
    }
  }
}
