/**
 * @license
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import {EventApi} from '@polymer/polymer/lib/legacy/polymer.dom';
import {check} from './common-util';

/**
 * Event emitted from polymer elements.
 */
export interface PolymerEvent extends EventApi, Event {}

interface ElementWithShadowRoot extends Element {
  shadowRoot: ShadowRoot;
}

/**
 * Type guard for element with a shadowRoot.
 */
function isElementWithShadowRoot(
  el: Element | ShadowRoot
): el is ElementWithShadowRoot {
  return 'shadowRoot' in el;
}

export function isElement(node: Node): node is Element {
  return node.nodeType === 1;
}

export function isElementTarget(
  target: EventTarget | null | undefined
): target is Element {
  if (!target) return false;
  return 'nodeType' in target && isElement(target as Node);
}

// TODO: maybe should have a better name for this
function getPathFromNode(el: EventTarget) {
  let tagName = '';
  let id = '';
  let className = '';
  if (el instanceof Element) {
    tagName = el.tagName;
    id = el.id;
    className = el.className;
  }
  if (
    !tagName ||
    'GR-APP' === tagName ||
    el instanceof DocumentFragment ||
    el instanceof HTMLSlotElement
  ) {
    return '';
  }
  let path = '';
  if (tagName) {
    path += tagName.toLowerCase();
  }
  if (id) {
    path += `#${id}`;
  }
  if (className) {
    path += `.${className.replace(/ /g, '.')}`;
  }
  return path;
}

/**
 * Get computed style value.
 */
export function getComputedStyleValue(name: string, el: Element) {
  return getComputedStyle(el).getPropertyValue(name).trim();
}

/**
 * Query selector on a dom element.
 *
 * This is shadow DOM compatible, but only works when selector is within
 * one shadow host, won't work if your selector is crossing
 * multiple shadow hosts.
 *
 */
export function querySelector(
  el: Element | ShadowRoot,
  selector: string
): Element | null {
  let nodes = [el];
  let result = null;
  while (nodes.length) {
    const node = nodes.pop();

    // Skip if it's an invalid node.
    if (!node || !node.querySelector) continue;

    // Try find it with native querySelector directly
    result = node.querySelector(selector);

    if (result) {
      break;
    }

    // Add all nodes with shadowRoot and loop through
    const allShadowNodes = [...node.querySelectorAll('*')]
      .filter(isElementWithShadowRoot)
      .map(child => child.shadowRoot);
    nodes = nodes.concat(allShadowNodes);

    // Add shadowRoot of current node if has one
    // as its not included in node.querySelectorAll('*')
    if (isElementWithShadowRoot(node)) {
      nodes.push(node.shadowRoot);
    }
  }
  return result;
}

/**
 * Query selector all dom elements matching with certain selector.
 *
 * This is shadow DOM compatible, but only works when selector is within
 * one shadow host, won't work if your selector is crossing
 * multiple shadow hosts.
 *
 * Note: this can be very expensive, only use when have to.
 */
export function querySelectorAll(
  el: Element | ShadowRoot,
  selector: string
): Element[] {
  let nodes = [el];
  const results = new Set<Element>();
  while (nodes.length) {
    const node = nodes.pop();

    if (!node || !node.querySelectorAll) continue;

    // Try find all from regular children
    [...node.querySelectorAll(selector)].forEach(el => results.add(el));

    // Add all nodes with shadowRoot and loop through
    const allShadowNodes = [...node.querySelectorAll('*')]
      .filter(isElementWithShadowRoot)
      .map(child => child.shadowRoot);
    nodes = nodes.concat(allShadowNodes);

    // Add shadowRoot of current node if has one
    // as its not included in node.querySelectorAll('*')
    if (isElementWithShadowRoot(node)) {
      nodes.push(node.shadowRoot);
    }
  }
  return [...results];
}

export function windowLocationReload() {
  const e = new Error();
  console.info(`Calling window.location.reload(): ${e.stack}`);
  window.location.reload();
}

/**
 * Retrieves the dom path of the current event.
 *
 * If the event object contains a `path` property, then use it,
 * otherwise, construct the dom path based on the event target.
 *
 * domNode.onclick = e => {
 *  getEventPath(e); // eg: div.class1>p#pid.class2
 * }
 */
export function getEventPath<T extends MouseEvent>(e?: T) {
  if (!e) return '';

  let path = e.composedPath();
  if (!path || !path.length) {
    path = [];
    let el = e.target;
    while (el) {
      path.push(el);
      el = (el as Node).parentNode || (el as ShadowRoot).host;
    }
  }

  return path.reduce<string>((domPath: string, curEl: EventTarget) => {
    const pathForEl = getPathFromNode(curEl);
    if (!pathForEl) return domPath;
    return domPath ? `${pathForEl}>${domPath}` : pathForEl;
  }, '');
}

/**
 * Are any ancestors of the element (or the element itself) members of the
 * given class.
 *
 */
export function descendedFromClass(
  element: Element,
  className: string,
  stopElement?: Element
) {
  let isDescendant = element.classList.contains(className);
  while (
    !isDescendant &&
    element.parentElement &&
    (!stopElement || element.parentElement !== stopElement)
  ) {
    isDescendant = element.classList.contains(className);
    element = element.parentElement;
  }
  return isDescendant;
}

/**
 * Convert any string into a valid class name.
 *
 * For class names, naming rules:
 * Must begin with a letter A-Z or a-z
 * Can be followed by: letters (A-Za-z), digits (0-9), hyphens ("-"), and underscores ("_")
 */
export function strToClassName(str = '', prefix = 'generated_') {
  return `${prefix}${str.replace(/[^a-zA-Z0-9-_]/g, '_')}`;
}

// document.activeElement is not enough, because it's not getting activeElement
// without looking inside of shadow roots. This will find best activeElement.
export function findActiveElement(
  root: Document | ShadowRoot | null,
  ignoreDialogs?: boolean
): HTMLElement | null {
  if (root === null) {
    return null;
  }
  if (
    ignoreDialogs &&
    root.activeElement &&
    root.activeElement.nodeName.toUpperCase().includes('DIALOG')
  ) {
    return null;
  }
  if (root.activeElement?.shadowRoot?.activeElement) {
    return findActiveElement(root.activeElement.shadowRoot);
  }
  if (!root.activeElement) {
    return null;
  }
  // We block some elements
  if ('BODY' === root.activeElement.nodeName.toUpperCase()) {
    return null;
  }
  return root.activeElement as HTMLElement;
}

// Whether the browser is Safari. Used for polyfilling unique browser behavior.
export function isSafari() {
  return (
    /^((?!chrome|android).)*safari/i.test(navigator.userAgent) ||
    /iPad|iPhone|iPod/.test(navigator.userAgent)
  );
}

export function whenVisible(
  element: Element,
  callback: () => void,
  marginPx = 0
) {
  const observer = new IntersectionObserver(
    (entries: IntersectionObserverEntry[]) => {
      check(entries.length === 1, 'Expected one intersection observer entry.');
      const entry = entries[0];
      if (entry.isIntersecting) {
        observer.unobserve(entry.target);
        callback();
      }
    },
    {rootMargin: `${marginPx}px`}
  );
  observer.observe(element);
}

/**
 * Toggles a CSS class on or off for an element.
 */
export function toggleClass(el: Element, className: string, bool?: boolean) {
  if (bool === undefined) {
    bool = !el.classList.contains(className);
  }
  if (bool) {
    el.classList.add(className);
  } else {
    el.classList.remove(className);
  }
}

/**
 * For matching the `key` property of KeyboardEvents. These are known to work
 * with Firefox, Safari and Chrome.
 */
export enum Key {
  ENTER = 'Enter',
  ESC = 'Escape',
  TAB = 'Tab',
  SPACE = ' ',
  LEFT = 'ArrowLeft',
  RIGHT = 'ArrowRight',
  UP = 'ArrowUp',
  DOWN = 'ArrowDown',
}

export enum Modifier {
  ALT_KEY,
  CTRL_KEY,
  META_KEY,
  SHIFT_KEY,
}

export enum ComboKey {
  G = 'g',
  V = 'v',
}

export interface Binding {
  key: string | Key;
  /** Defaults to false. */
  docOnly?: boolean;
  /** Defaults to not being a combo shortcut. */
  combo?: ComboKey;
  /** Defaults to no modifiers. */
  modifiers?: Modifier[];
}

const ALPHA_NUM = new RegExp(/^[A-Za-z0-9]$/);

/**
 * For "normal" keys we do not check that the SHIFT modifier is pressed or not,
 * because that depends on the keyboard layout. Just checking the key string is
 * sufficient.
 *
 * But for some special keys it is important whether SHIFT is pressed at the
 * same time, for example we want to distinguish Enter from Shift+Enter.
 */
function shiftMustMatch(key: string | Key) {
  return Object.values(Key).includes(key as Key);
}

/**
 * For a-zA-Z0-9 and for Enter, Tab, etc. we want to check the ALT modifier.
 *
 * But for special chars like []/? we don't care whether the user is pressing
 * the ALT modifier to produce the special char. For example on a German
 * keyboard layout you have to press ALT to produce a [.
 */
function altMustMatch(key: string | Key) {
  return ALPHA_NUM.test(key) || Object.values(Key).includes(key as Key);
}

export function eventMatchesShortcut(
  e: KeyboardEvent,
  shortcut: Binding
): boolean {
  if (e.key !== shortcut.key) return false;
  const modifiers = shortcut.modifiers ?? [];
  if (e.ctrlKey !== modifiers.includes(Modifier.CTRL_KEY)) return false;
  if (e.metaKey !== modifiers.includes(Modifier.META_KEY)) return false;
  if (
    altMustMatch(e.key) &&
    e.altKey !== modifiers.includes(Modifier.ALT_KEY)
  ) {
    return false;
  }
  if (
    shiftMustMatch(e.key) &&
    e.shiftKey !== modifiers.includes(Modifier.SHIFT_KEY)
  ) {
    return false;
  }
  return true;
}

export function addGlobalShortcut(
  shortcut: Binding,
  listener: (e: KeyboardEvent) => void
) {
  return addShortcut(document.body, shortcut, listener);
}

export function addShortcut(
  element: HTMLElement,
  shortcut: Binding,
  listener: (e: KeyboardEvent) => void,
  options: {
    shouldSuppress: boolean;
  } = {
    shouldSuppress: false,
  }
) {
  const wrappedListener = (e: KeyboardEvent) => {
    if (e.repeat) return;
    if (options.shouldSuppress && shouldSuppress(e)) return;
    if (eventMatchesShortcut(e, shortcut)) {
      listener(e);
    }
  };
  element.addEventListener('keydown', wrappedListener);
  return () => element.removeEventListener('keydown', wrappedListener);
}

export function modifierPressed(e: KeyboardEvent) {
  return e.altKey || e.ctrlKey || e.metaKey || e.shiftKey;
}

export function shiftPressed(e: KeyboardEvent) {
  return e.shiftKey;
}

/**
 * When you listen on keyboard events, then within Gerrit's web app you may want
 * to avoid firing in certain common scenarios such as key strokes from <input>
 * elements. But this can also be undesirable, for example Ctrl-Enter from
 * <input> should trigger a save event.
 *
 * The shortcuts-service has a stateful method `shouldSuppress()` with
 * reporting functionality, which delegates to here.
 */
export function shouldSuppress(e: KeyboardEvent): boolean {
  // Note that when you listen on document, then `e.currentTarget` will be the
  // document and `e.target` will be `<gr-app>` due to shadow dom, but by
  // using the composedPath() you can actually find the true origin of the
  // event.
  const rootTarget = e.composedPath()[0];
  if (!isElementTarget(rootTarget)) return false;
  const tagName = rootTarget.tagName;
  const type = rootTarget.getAttribute('type');

  if (
    // Suppress shortcuts on <input> and <textarea>, but not on
    // checkboxes, because we want to enable workflows like 'click
    // mark-reviewed and then press ] to go to the next file'.
    (tagName === 'INPUT' && type !== 'checkbox') ||
    tagName === 'TEXTAREA' ||
    // Suppress shortcuts if the key is 'enter'
    // and target is an anchor or button or paper-tab.
    (e.keyCode === 13 &&
      (tagName === 'A' ||
        tagName === 'BUTTON' ||
        tagName === 'GR-BUTTON' ||
        tagName === 'PAPER-TAB'))
  ) {
    return true;
  }
  const path: EventTarget[] = e.composedPath() ?? [];
  for (const el of path) {
    if (!isElementTarget(el)) continue;
    if (el.tagName === 'GR-OVERLAY') return true;
  }
  return false;
}
