/**
 * @module modules/gold-scaffold-sk
 * @description <h2><code>gold-scaffold-sk</code></h2>
 *
 * Contains the title bar, side bar, and error-toast for all the Gold pages. The rest of
 * every Gold page should be a child of this element.
 *
 * Has a spinner-sk that can be activated when it hears "begin-task" events and keeps
 * spinning until it hears an equal number of "end-task" events.
 *
 * The error-toast element responds to fetch-error events and normal error-sk events.
 *
 * @attr {boolean} testing_offline - If we should operate entirely in offline mode.
 */
import { define } from 'elements-sk/define';
import { errorMessage } from 'elements-sk/errorMessage';
import { html } from 'lit-html';
import { ElementSk } from '../../../infra-sk/modules/ElementSk';
import { title } from '../settings';
import { SpinnerSk } from 'elements-sk/spinner-sk/spinner-sk';
import { FetchErrorEventDetail } from '../common';

import '../../../infra-sk/modules/app-sk';
import '../../../infra-sk/modules/login-sk';

import '../last-commit-sk';

import 'elements-sk/error-toast-sk';
import 'elements-sk/icon/find-in-page-icon-sk';
import 'elements-sk/icon/folder-icon-sk';
import 'elements-sk/icon/help-icon-sk';
import 'elements-sk/icon/home-icon-sk';
import 'elements-sk/icon/label-icon-sk';
import 'elements-sk/icon/laptop-chromebook-icon-sk';
import 'elements-sk/icon/list-icon-sk';
import 'elements-sk/icon/search-icon-sk';
import 'elements-sk/icon/sync-problem-icon-sk';
import 'elements-sk/icon/view-day-icon-sk';
import 'elements-sk/spinner-sk';

/** Moves the elements in a NodeList or HTMLCollection as children of another element. */
function move(from: HTMLCollection | NodeList, to: HTMLElement) {
  Array.prototype.slice.call(from).forEach((ele) => to.appendChild(ele));
}

export class GoldScaffoldSk extends ElementSk {
  private static template = (ele: GoldScaffoldSk) => html`
    <app-sk>
      <header>
        <h1>${title()}</h1>
        <div class=spinner-spacer>
          <spinner-sk></spinner-sk>
        </div>
        <div class=spacer></div>
        <last-commit-sk></last-commit-sk>
        <login-sk ?testing_offline=${ele.testingOffline}
                  .loginHost=${window.location.host}></login-sk>
      </header>

      <aside>
        <nav>
          <a href="/" tab-index=0>
            <home-icon-sk></home-icon-sk><span>Home</span>
          </a>
          <a href="/" tab-index=0>
            <view-day-icon-sk></view-day-icon-sk><span>By Blame<span>
          </a>
          <a href="/list" tab-index=0>
            <list-icon-sk></list-icon-sk><span>By Test</span>
          </a>
          <a href="/changelists" tab-index=0>
            <laptop-chromebook-icon-sk></laptop-chromebook-icon-sk><span>By ChangeList</span>
          </a>
          <a href="/search" tab-index=0>
            <search-icon-sk></search-icon-sk><span>Search</span>
          </a>
          <a href="/ignores" tab-index=0>
            <label-icon-sk></label-icon-sk><span>Ignores</span>
          </a>
          <a href="/triagelog" tab-index=0>
            <find-in-page-icon-sk></find-in-page-icon-sk><span>Triage Log</span>
          </a>
          <a href="/help" tab-index=0>
            <help-icon-sk></help-icon-sk><span>Help</span>
          </a>
          <a href="https://github.com/google/skia-buildbot/tree/master/golden" tab-index=0>
            <folder-icon-sk></folder-icon-sk><span>Code</span>
          </a>
        </nav>
      </aside>

      <main></main>

      <footer><error-toast-sk></error-toast-sk></footer>
    </app-sk>
  `;

  private main: HTMLElement | null = null;
  private busyTaskCount = 0;
  private spinner: SpinnerSk | null = null;

  constructor() {
    super(GoldScaffoldSk.template);
  }

  connectedCallback() {
    super.connectedCallback();
    // Don't call more than once.
    if (this.main) {
      return;
    }
    this.addEventListener('begin-task', this.addBusyTask);
    this.addEventListener('end-task', this.finishedTask);
    this.addEventListener('fetch-error', this.fetchError);

    // We aren't using shadow dom so we need to manually move the children of
    // gold-scaffold-sk to be children of 'main'. We have to do this for the
    // existing elements and for all future mutations.

    // Create a temporary holding spot for elements we're moving.
    const div = document.createElement('div');
    move(this.children, div);

    // Now that we've moved all the old children out of the way we can render
    // the template.
    this._render();

    this.spinner = this.querySelector<SpinnerSk>('header spinner-sk');

    // Move the old children back under main.
    this.main = this.querySelector('main');
    move(div.children, this.main!);

    // Move all future children under main also.
    const observer = new MutationObserver((mutList) => {
      mutList.forEach((mut) => {
        move(mut.addedNodes, this.main!);
      });
    });
    observer.observe(this, { childList: true });
  }

  disconnectedCallback() {
    super.disconnectedCallback();
    this.removeEventListener('begin-task', this.addBusyTask);
    this.removeEventListener('end-task', this.finishedTask);
    this.removeEventListener('fetch-error', this.fetchError);
  }

  /**
   * Indicates if there any on-going tasks (e.g. RPCs). This also mirrors the status of the
   * embedded spinner-sk.
   */
  get busy() { return !!this.busyTaskCount; }

  /** Reflects the testing_offline attribute for ease of use. */
  get testingOffline() { return this.hasAttribute('testing_offline'); }

  set testingOffline(val) {
    if (val) {
      this.setAttribute('testing_offline', '');
    } else {
      this.removeAttribute('testing_offline');
    }
  }

  /**
   * Indicate there are some number of tasks (e.g. RPCs) the app is waiting on and should be in the
   * "busy" state, if it isn't already.
   */
  private addBusyTask() {
    this.busyTaskCount++;
    if (this.spinner && this.busyTaskCount > 0) {
      this.spinner.active = true;
    }
  }

  /**
   * Removes one task from the busy count. If there are no more tasks to wait for, the app will
   * leave the "busy" state and emit the "busy-end" event.
   */
  private finishedTask() {
    this.busyTaskCount--;
    if (this.busyTaskCount <= 0) {
      this.busyTaskCount = 0;
      if (this.spinner) {
        this.spinner.active = false;
      }
      this.dispatchEvent(new CustomEvent('busy-end', { bubbles: true }));
    }
  }

  /** Handles a fetch-error event. */
  private fetchError(e: Event) {
    // Method removeEventListener expects an Event, so we're forced to take an Event and cast it as
    // a CustomEvent here.
    const fetchErrorEvent = e as CustomEvent<FetchErrorEventDetail>;
    const error = fetchErrorEvent.detail.error;
    const loadingWhat = fetchErrorEvent.detail.loading;
    if (fetchErrorEvent.detail.error.name !== 'AbortError') {
      // We can ignore AbortError since they fire anytime an AbortController was canceled.
      // Chrome and Firefox report a DOMException in this case:
      // https://developer.mozilla.org/en-US/docs/Web/API/DOMException
      console.error(error);
      errorMessage(`Unexpected error loading ${loadingWhat}: ${error.message}`, 5000);
    }
    this.finishedTask();
  }
}

define('gold-scaffold-sk', GoldScaffoldSk);
