/**
 * @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 { SpinnerSk } from 'elements-sk/spinner-sk/spinner-sk';
import { ElementSk } from '../../../infra-sk/modules/ElementSk';
import { title } from '../settings';
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) {
      // We still want to re-render in case the GoldSettings have changed (e.g. the title), which
      // is common in tests.
      this._render();
      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);
