/**
 * @license
 * Copyright (C) 2016 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.
 */
/*

How to Add a Keyboard Shortcut
==============================

A keyboard shortcut is composed of the following parts:

  1. A semantic identifier (e.g. OPEN_CHANGE, NEXT_PAGE)
  2. Documentation for the keyboard shortcut help dialog
  3. A binding between key combos and the semantic identifier
  4. A binding between the semantic identifier and a listener

Parts (1) and (2) for all shortcuts are defined in this file. The semantic
identifier is declared in the Shortcut enum near the head of this script:

  const Shortcut = {
    // ...
    TOGGLE_LEFT_PANE: 'TOGGLE_LEFT_PANE',
    // ...
  };

Immediately following the Shortcut enum definition, there is a _describe
function defined which is then invoked many times to populate the help dialog.
Add a new invocation here to document the shortcut:

  _describe(Shortcut.TOGGLE_LEFT_PANE, ShortcutSection.DIFFS,
      'Hide/show left diff');

When an attached view binds one or more key combos to this shortcut, the help
dialog will display this text in the given section (in this case, "Diffs"). See
the ShortcutSection enum immediately below for the list of supported sections.

Part (3), the actual key bindings, are declared by gr-app. In the future, this
system may be expanded to allow key binding customizations by plugins or user
preferences. Key bindings are defined in the following forms:

  // Ordinary shortcut with a single binding.
  this.bindShortcut(
      this.Shortcut.TOGGLE_LEFT_PANE, 'shift+a');

  // Ordinary shortcut with multiple bindings.
  this.bindShortcut(
      this.Shortcut.CURSOR_NEXT_FILE, 'j', 'down');

  // A "go-key" keyboard shortcut, which is combined with a previously and
  // continuously pressed "go" key (the go-key is hard-coded as 'g').
  this.bindShortcut(
      this.Shortcut.GO_TO_OPENED_CHANGES, this.GO_KEY, 'o');

  // A "doc-only" keyboard shortcut. This declares the key-binding for help
  // dialog purposes, but doesn't actually implement the binding. It is up
  // to some element to implement this binding using iron-a11y-keys-behavior's
  // keyBindings property.
  this.bindShortcut(
      this.Shortcut.EXPAND_ALL_COMMENT_THREADS, this.DOC_ONLY, 'e');

Part (4), the listener definitions, are declared by the view or element that
implements the shortcut behavior. This is done by implementing a method named
keyboardShortcuts() in an element that mixes in this behavior, returning an
object that maps semantic identifiers (as property names) to listener method
names, like this:

  keyboardShortcuts() {
    return {
      [this.Shortcut.TOGGLE_LEFT_PANE]: '_handleToggleLeftPane',
    };
  },

You can implement key bindings in an element that is hosted by a view IF that
element is always attached exactly once under that view (e.g. the search bar in
gr-app). When that is not the case, you will have to define a doc-only binding
in gr-app, declare the shortcut in the view that hosts the element, and use
iron-a11y-keys-behavior's keyBindings attribute to implement the binding in the
element. An example of this is in comment threads. A diff view supports actions
on comment threads, but there may be zero or many comment threads attached at
any given point. So the shortcut is declared as doc-only by the diff view and
by gr-app, and actually implemented by gr-comment-thread.

NOTE: doc-only shortcuts will not be customizable in the same way that other
shortcuts are.
*/

import {IronA11yKeysBehavior} from '@polymer/iron-a11y-keys-behavior/iron-a11y-keys-behavior.js';
import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';

const DOC_ONLY = 'DOC_ONLY';
const GO_KEY = 'GO_KEY';
const V_KEY = 'V_KEY';

// The maximum age of a keydown event to be used in a jump navigation. This
// is only for cases when the keyup event is lost.
const GO_KEY_TIMEOUT_MS = 1000;

const V_KEY_TIMEOUT_MS = 1000;

const ShortcutSection = {
  ACTIONS: 'Actions',
  DIFFS: 'Diffs',
  EVERYWHERE: 'Everywhere',
  FILE_LIST: 'File list',
  NAVIGATION: 'Navigation',
  REPLY_DIALOG: 'Reply dialog',
};

const Shortcut = {
  OPEN_SHORTCUT_HELP_DIALOG: 'OPEN_SHORTCUT_HELP_DIALOG',
  GO_TO_USER_DASHBOARD: 'GO_TO_USER_DASHBOARD',
  GO_TO_OPENED_CHANGES: 'GO_TO_OPENED_CHANGES',
  GO_TO_MERGED_CHANGES: 'GO_TO_MERGED_CHANGES',
  GO_TO_ABANDONED_CHANGES: 'GO_TO_ABANDONED_CHANGES',
  GO_TO_WATCHED_CHANGES: 'GO_TO_WATCHED_CHANGES',

  CURSOR_NEXT_CHANGE: 'CURSOR_NEXT_CHANGE',
  CURSOR_PREV_CHANGE: 'CURSOR_PREV_CHANGE',
  OPEN_CHANGE: 'OPEN_CHANGE',
  NEXT_PAGE: 'NEXT_PAGE',
  PREV_PAGE: 'PREV_PAGE',
  TOGGLE_CHANGE_REVIEWED: 'TOGGLE_CHANGE_REVIEWED',
  TOGGLE_CHANGE_STAR: 'TOGGLE_CHANGE_STAR',
  REFRESH_CHANGE_LIST: 'REFRESH_CHANGE_LIST',

  OPEN_REPLY_DIALOG: 'OPEN_REPLY_DIALOG',
  OPEN_DOWNLOAD_DIALOG: 'OPEN_DOWNLOAD_DIALOG',
  EXPAND_ALL_MESSAGES: 'EXPAND_ALL_MESSAGES',
  COLLAPSE_ALL_MESSAGES: 'COLLAPSE_ALL_MESSAGES',
  UP_TO_DASHBOARD: 'UP_TO_DASHBOARD',
  UP_TO_CHANGE: 'UP_TO_CHANGE',
  TOGGLE_DIFF_MODE: 'TOGGLE_DIFF_MODE',
  REFRESH_CHANGE: 'REFRESH_CHANGE',
  EDIT_TOPIC: 'EDIT_TOPIC',
  DIFF_AGAINST_BASE: 'DIFF_AGAINST_BASE',
  DIFF_AGAINST_LATEST: 'DIFF_AGAINST_LATEST',
  DIFF_BASE_AGAINST_LEFT: 'DIFF_BASE_AGAINST_LEFT',
  DIFF_RIGHT_AGAINST_LATEST: 'DIFF_RIGHT_AGAINST_LATEST',
  DIFF_BASE_AGAINST_LATEST: 'DIFF_BASE_AGAINST_LATEST',

  NEXT_LINE: 'NEXT_LINE',
  PREV_LINE: 'PREV_LINE',
  VISIBLE_LINE: 'VISIBLE_LINE',
  NEXT_CHUNK: 'NEXT_CHUNK',
  PREV_CHUNK: 'PREV_CHUNK',
  EXPAND_ALL_DIFF_CONTEXT: 'EXPAND_ALL_DIFF_CONTEXT',
  NEXT_COMMENT_THREAD: 'NEXT_COMMENT_THREAD',
  PREV_COMMENT_THREAD: 'PREV_COMMENT_THREAD',
  EXPAND_ALL_COMMENT_THREADS: 'EXPAND_ALL_COMMENT_THREADS',
  COLLAPSE_ALL_COMMENT_THREADS: 'COLLAPSE_ALL_COMMENT_THREADS',
  LEFT_PANE: 'LEFT_PANE',
  RIGHT_PANE: 'RIGHT_PANE',
  TOGGLE_LEFT_PANE: 'TOGGLE_LEFT_PANE',
  NEW_COMMENT: 'NEW_COMMENT',
  SAVE_COMMENT: 'SAVE_COMMENT',
  OPEN_DIFF_PREFS: 'OPEN_DIFF_PREFS',
  TOGGLE_DIFF_REVIEWED: 'TOGGLE_DIFF_REVIEWED',

  NEXT_FILE: 'NEXT_FILE',
  PREV_FILE: 'PREV_FILE',
  NEXT_FILE_WITH_COMMENTS: 'NEXT_FILE_WITH_COMMENTS',
  PREV_FILE_WITH_COMMENTS: 'PREV_FILE_WITH_COMMENTS',
  NEXT_UNREVIEWED_FILE: 'NEXT_UNREVIEWED_FILE',
  CURSOR_NEXT_FILE: 'CURSOR_NEXT_FILE',
  CURSOR_PREV_FILE: 'CURSOR_PREV_FILE',
  OPEN_FILE: 'OPEN_FILE',
  TOGGLE_FILE_REVIEWED: 'TOGGLE_FILE_REVIEWED',
  TOGGLE_ALL_INLINE_DIFFS: 'TOGGLE_ALL_INLINE_DIFFS',
  TOGGLE_INLINE_DIFF: 'TOGGLE_INLINE_DIFF',
  TOGGLE_HIDE_ALL_COMMENT_THREADS: 'TOGGLE_HIDE_ALL_COMMENT_THREADS',

  OPEN_FIRST_FILE: 'OPEN_FIRST_FILE',
  OPEN_LAST_FILE: 'OPEN_LAST_FILE',

  SEARCH: 'SEARCH',
  SEND_REPLY: 'SEND_REPLY',
  EMOJI_DROPDOWN: 'EMOJI_DROPDOWN',
  TOGGLE_BLAME: 'TOGGLE_BLAME',
};

const _help = new Map();

function _describe(shortcut, section, text) {
  if (!_help.has(section)) {
    _help.set(section, []);
  }
  _help.get(section).push({shortcut, text});
}

_describe(Shortcut.SEARCH, ShortcutSection.EVERYWHERE, 'Search');
_describe(Shortcut.OPEN_SHORTCUT_HELP_DIALOG, ShortcutSection.EVERYWHERE,
    'Show this dialog');
_describe(Shortcut.GO_TO_USER_DASHBOARD, ShortcutSection.EVERYWHERE,
    'Go to User Dashboard');
_describe(Shortcut.GO_TO_OPENED_CHANGES, ShortcutSection.EVERYWHERE,
    'Go to Opened Changes');
_describe(Shortcut.GO_TO_MERGED_CHANGES, ShortcutSection.EVERYWHERE,
    'Go to Merged Changes');
_describe(Shortcut.GO_TO_ABANDONED_CHANGES, ShortcutSection.EVERYWHERE,
    'Go to Abandoned Changes');
_describe(Shortcut.GO_TO_WATCHED_CHANGES, ShortcutSection.EVERYWHERE,
    'Go to Watched Changes');

_describe(Shortcut.CURSOR_NEXT_CHANGE, ShortcutSection.ACTIONS,
    'Select next change');
_describe(Shortcut.CURSOR_PREV_CHANGE, ShortcutSection.ACTIONS,
    'Select previous change');
_describe(Shortcut.OPEN_CHANGE, ShortcutSection.ACTIONS,
    'Show selected change');
_describe(Shortcut.NEXT_PAGE, ShortcutSection.ACTIONS, 'Go to next page');
_describe(Shortcut.PREV_PAGE, ShortcutSection.ACTIONS, 'Go to previous page');
_describe(Shortcut.OPEN_REPLY_DIALOG, ShortcutSection.ACTIONS,
    'Open reply dialog to publish comments and add reviewers');
_describe(Shortcut.OPEN_DOWNLOAD_DIALOG, ShortcutSection.ACTIONS,
    'Open download overlay');
_describe(Shortcut.EXPAND_ALL_MESSAGES, ShortcutSection.ACTIONS,
    'Expand all messages');
_describe(Shortcut.COLLAPSE_ALL_MESSAGES, ShortcutSection.ACTIONS,
    'Collapse all messages');
_describe(Shortcut.REFRESH_CHANGE, ShortcutSection.ACTIONS,
    'Reload the change at the latest patch');
_describe(Shortcut.TOGGLE_CHANGE_REVIEWED, ShortcutSection.ACTIONS,
    'Mark/unmark change as reviewed');
_describe(Shortcut.TOGGLE_FILE_REVIEWED, ShortcutSection.ACTIONS,
    'Toggle review flag on selected file');
_describe(Shortcut.REFRESH_CHANGE_LIST, ShortcutSection.ACTIONS,
    'Refresh list of changes');
_describe(Shortcut.TOGGLE_CHANGE_STAR, ShortcutSection.ACTIONS,
    'Star/unstar change');
_describe(Shortcut.EDIT_TOPIC, ShortcutSection.ACTIONS,
    'Add a change topic');
_describe(Shortcut.DIFF_AGAINST_BASE, ShortcutSection.ACTIONS,
    'Diff against base');
_describe(Shortcut.DIFF_AGAINST_LATEST, ShortcutSection.ACTIONS,
    'Diff against latest patchset');
_describe(Shortcut.DIFF_BASE_AGAINST_LEFT, ShortcutSection.ACTIONS,
    'Diff base against left');
_describe(Shortcut.DIFF_RIGHT_AGAINST_LATEST, ShortcutSection.ACTIONS,
    'Diff right against latest');
_describe(Shortcut.DIFF_BASE_AGAINST_LATEST, ShortcutSection.ACTIONS,
    'Diff base against latest');

_describe(Shortcut.NEXT_LINE, ShortcutSection.DIFFS, 'Go to next line');
_describe(Shortcut.PREV_LINE, ShortcutSection.DIFFS, 'Go to previous line');
_describe(Shortcut.DIFF_AGAINST_BASE, ShortcutSection.DIFFS,
    'Diff against base');
_describe(Shortcut.DIFF_AGAINST_LATEST, ShortcutSection.DIFFS,
    'Diff against latest patchset');
_describe(Shortcut.DIFF_BASE_AGAINST_LEFT, ShortcutSection.DIFFS,
    'Diff base against left');
_describe(Shortcut.DIFF_RIGHT_AGAINST_LATEST, ShortcutSection.DIFFS,
    'Diff right against latest');
_describe(Shortcut.DIFF_BASE_AGAINST_LATEST, ShortcutSection.DIFFS,
    'Diff base against latest');
_describe(Shortcut.VISIBLE_LINE, ShortcutSection.DIFFS,
    'Move cursor to currently visible code');
_describe(Shortcut.NEXT_CHUNK, ShortcutSection.DIFFS,
    'Go to next diff chunk');
_describe(Shortcut.PREV_CHUNK, ShortcutSection.DIFFS,
    'Go to previous diff chunk');
_describe(Shortcut.EXPAND_ALL_DIFF_CONTEXT, ShortcutSection.DIFFS,
    'Expand all diff context');
_describe(Shortcut.NEXT_COMMENT_THREAD, ShortcutSection.DIFFS,
    'Go to next comment thread');
_describe(Shortcut.PREV_COMMENT_THREAD, ShortcutSection.DIFFS,
    'Go to previous comment thread');
_describe(Shortcut.EXPAND_ALL_COMMENT_THREADS, ShortcutSection.DIFFS,
    'Expand all comment threads');
_describe(Shortcut.COLLAPSE_ALL_COMMENT_THREADS, ShortcutSection.DIFFS,
    'Collapse all comment threads');
_describe(Shortcut.TOGGLE_HIDE_ALL_COMMENT_THREADS, ShortcutSection.DIFFS,
    'Hide/Display all comment threads');
_describe(Shortcut.LEFT_PANE, ShortcutSection.DIFFS, 'Select left pane');
_describe(Shortcut.RIGHT_PANE, ShortcutSection.DIFFS, 'Select right pane');
_describe(Shortcut.TOGGLE_LEFT_PANE, ShortcutSection.DIFFS,
    'Hide/show left diff');
_describe(Shortcut.NEW_COMMENT, ShortcutSection.DIFFS, 'Draft new comment');
_describe(Shortcut.SAVE_COMMENT, ShortcutSection.DIFFS, 'Save comment');
_describe(Shortcut.OPEN_DIFF_PREFS, ShortcutSection.DIFFS,
    'Show diff preferences');
_describe(Shortcut.TOGGLE_DIFF_REVIEWED, ShortcutSection.DIFFS,
    'Mark/unmark file as reviewed');
_describe(Shortcut.TOGGLE_DIFF_MODE, ShortcutSection.DIFFS,
    'Toggle unified/side-by-side diff');
_describe(Shortcut.NEXT_UNREVIEWED_FILE, ShortcutSection.DIFFS,
    'Mark file as reviewed and go to next unreviewed file');
_describe(Shortcut.TOGGLE_BLAME, ShortcutSection.DIFFS, 'Toggle blame');

_describe(Shortcut.NEXT_FILE, ShortcutSection.NAVIGATION, 'Go to next file');
_describe(Shortcut.PREV_FILE, ShortcutSection.NAVIGATION,
    'Go to previous file');
_describe(Shortcut.NEXT_FILE_WITH_COMMENTS, ShortcutSection.NAVIGATION,
    'Go to next file that has comments');
_describe(Shortcut.PREV_FILE_WITH_COMMENTS, ShortcutSection.NAVIGATION,
    'Go to previous file that has comments');
_describe(Shortcut.OPEN_FIRST_FILE, ShortcutSection.NAVIGATION,
    'Go to first file');
_describe(Shortcut.OPEN_LAST_FILE, ShortcutSection.NAVIGATION,
    'Go to last file');
_describe(Shortcut.UP_TO_DASHBOARD, ShortcutSection.NAVIGATION,
    'Up to dashboard');
_describe(Shortcut.UP_TO_CHANGE, ShortcutSection.NAVIGATION, 'Up to change');

_describe(Shortcut.CURSOR_NEXT_FILE, ShortcutSection.FILE_LIST,
    'Select next file');
_describe(Shortcut.CURSOR_PREV_FILE, ShortcutSection.FILE_LIST,
    'Select previous file');
_describe(Shortcut.OPEN_FILE, ShortcutSection.FILE_LIST,
    'Go to selected file');
_describe(Shortcut.TOGGLE_ALL_INLINE_DIFFS, ShortcutSection.FILE_LIST,
    'Show/hide all inline diffs');
_describe(Shortcut.TOGGLE_HIDE_ALL_COMMENT_THREADS, ShortcutSection.FILE_LIST,
    'Hide/Display all comment threads');
_describe(Shortcut.TOGGLE_INLINE_DIFF, ShortcutSection.FILE_LIST,
    'Show/hide selected inline diff');

_describe(Shortcut.SEND_REPLY, ShortcutSection.REPLY_DIALOG, 'Send reply');
_describe(Shortcut.EMOJI_DROPDOWN, ShortcutSection.REPLY_DIALOG,
    'Emoji dropdown');

// Must be declared outside behavior implementation to be accessed inside
// behavior functions.

/** @return {!(Event|PolymerDomApi|PolymerEventApi)} */
const getKeyboardEvent = function(e) {
  e = dom(e.detail ? e.detail.keyboardEvent : e);
  // When e is a keyboardEvent, e.event is not null.
  if (e.event) { e = e.event; }
  return e;
};

class ShortcutManager {
  constructor() {
    this.activeHosts = new Map();
    this.bindings = new Map();
    this.listeners = new Set();
  }

  bindShortcut(shortcut, ...bindings) {
    this.bindings.set(shortcut, bindings);
  }

  getBindingsForShortcut(shortcut) {
    return this.bindings.get(shortcut);
  }

  attachHost(host) {
    if (!host.keyboardShortcuts) { return; }
    const shortcuts = host.keyboardShortcuts();
    this.activeHosts.set(host, new Map(Object.entries(shortcuts)));
    this.notifyListeners();
    return shortcuts;
  }

  detachHost(host) {
    if (this.activeHosts.delete(host)) {
      this.notifyListeners();
      return true;
    }
    return false;
  }

  addListener(listener) {
    this.listeners.add(listener);
    listener(this.directoryView());
  }

  removeListener(listener) {
    return this.listeners.delete(listener);
  }

  getDescription(section, shortcutName) {
    const binding =
        _help.get(section).find(binding => binding.shortcut == shortcutName);
    return binding ? binding.text : '';
  }

  getShortcut(shortcutName) {
    const binding = this.bindings.get(shortcutName);
    return binding ? this.describeBinding(binding) : '';
  }

  activeShortcutsBySection() {
    const activeShortcuts = new Set();
    this.activeHosts.forEach(shortcuts => {
      shortcuts.forEach((_, shortcut) => activeShortcuts.add(shortcut));
    });

    const activeShortcutsBySection = new Map();
    _help.forEach((shortcutList, section) => {
      shortcutList.forEach(shortcutHelp => {
        if (activeShortcuts.has(shortcutHelp.shortcut)) {
          if (!activeShortcutsBySection.has(section)) {
            activeShortcutsBySection.set(section, []);
          }
          activeShortcutsBySection.get(section).push(shortcutHelp);
        }
      });
    });
    return activeShortcutsBySection;
  }

  directoryView() {
    const view = new Map();
    this.activeShortcutsBySection().forEach((shortcutHelps, section) => {
      const sectionView = [];
      shortcutHelps.forEach(shortcutHelp => {
        const bindingDesc = this.describeBindings(shortcutHelp.shortcut);
        if (!bindingDesc) { return; }
        this.distributeBindingDesc(bindingDesc).forEach(bindingDesc => {
          sectionView.push({
            binding: bindingDesc,
            text: shortcutHelp.text,
          });
        });
      });
      view.set(section, sectionView);
    });
    return view;
  }

  distributeBindingDesc(bindingDesc) {
    if (bindingDesc.length === 1 ||
        this.comboSetDisplayWidth(bindingDesc) < 21) {
      return [bindingDesc];
    }
    // Find the largest prefix of bindings that is under the
    // size threshold.
    const head = [bindingDesc[0]];
    for (let i = 1; i < bindingDesc.length; i++) {
      head.push(bindingDesc[i]);
      if (this.comboSetDisplayWidth(head) >= 21) {
        head.pop();
        return [head].concat(
            this.distributeBindingDesc(bindingDesc.slice(i)));
      }
    }
  }

  comboSetDisplayWidth(bindingDesc) {
    const bindingSizer = binding => binding.reduce(
        (acc, key) => acc + key.length, 0);
    // Width is the sum of strings + (n-1) * 2 to account for the word
    // "or" joining them.
    return bindingDesc.reduce(
        (acc, binding) => acc + bindingSizer(binding), 0) +
        2 * (bindingDesc.length - 1);
  }

  describeBindings(shortcut) {
    const bindings = this.bindings.get(shortcut);
    if (!bindings) { return null; }
    if (bindings[0] === GO_KEY) {
      return bindings.slice(1).map(
          binding => this._describeKey(binding)
      )
          .map(binding => ['g'].concat(binding));
    }
    if (bindings[0] === V_KEY) {
      return bindings.slice(1).map(
          binding => this._describeKey(binding)
      )
          .map(binding => ['v'].concat(binding));
    }
    return bindings
        .filter(binding => binding !== DOC_ONLY)
        .map(binding => this.describeBinding(binding));
  }

  _describeKey(key) {
    switch (key) {
      case 'shift':
        return 'Shift';
      case 'meta':
        return 'Meta';
      case 'ctrl':
        return 'Ctrl';
      case 'enter':
        return 'Enter';
      case 'up':
        return '↑';
      case 'down':
        return '↓';
      case 'left':
        return '←';
      case 'right':
        return '→';
      default:
        return key;
    }
  }

  describeBinding(binding) {
    if (binding.length === 1) {
      return [binding];
    }
    return binding.split(':')[0].split('+').map(part =>
      this._describeKey(part)
    );
  }

  notifyListeners() {
    const view = this.directoryView();
    this.listeners.forEach(listener => listener(view));
  }
}

const shortcutManager = new ShortcutManager();

/** @polymerBehavior Gerrit.KeyboardShortcutBehavior*/
export const KeyboardShortcutBehavior = [
  IronA11yKeysBehavior,
  {
    // Exports for convenience. Note: Closure compiler crashes when
    // object-shorthand syntax is used here.
    // eslint-disable-next-line object-shorthand
    DOC_ONLY: DOC_ONLY,
    // eslint-disable-next-line object-shorthand
    GO_KEY: GO_KEY,
    // eslint-disable-next-line object-shorthand
    V_KEY: V_KEY,
    // eslint-disable-next-line object-shorthand
    Shortcut: Shortcut,
    // eslint-disable-next-line object-shorthand
    ShortcutSection: ShortcutSection,

    properties: {
      _shortcut_go_key_last_pressed: {
        type: Number,
        value: null,
      },
      _shortcut_go_table: {
        type: Array,
        value() { return new Map(); },
      },
      _shortcut_v_table: {
        type: Array,
        value() { return new Map(); },
      },
    },

    modifierPressed(e) {
      e = getKeyboardEvent(e);
      return e.altKey || e.ctrlKey || e.metaKey || e.shiftKey ||
        !!this._inGoKeyMode() || !!this._inVKeyMode();
    },

    isModifierPressed(e, modifier) {
      return getKeyboardEvent(e)[modifier];
    },

    shouldSuppressKeyboardShortcut(e) {
      e = getKeyboardEvent(e);
      const tagName = dom(e).rootTarget.tagName;
      if (tagName === 'INPUT' || tagName === 'TEXTAREA' ||
          (e.keyCode === 13 && tagName === 'A')) {
        // Suppress shortcuts if the key is 'enter' and target is an anchor.
        return true;
      }
      for (let i = 0; e.path && i < e.path.length; i++) {
        if (e.path[i].tagName === 'GR-OVERLAY') { return true; }
      }

      this.dispatchEvent(new CustomEvent('shortcut-triggered', {
        detail: {
          event: e,
          goKey: this._inGoKeyMode(),
        },
        composed: true, bubbles: true,
      }));
      return false;
    },

    // Alias for getKeyboardEvent.
    /** @return {!Event} */
    getKeyboardEvent(e) {
      return getKeyboardEvent(e);
    },

    getRootTarget(e) {
      return dom(getKeyboardEvent(e)).rootTarget;
    },

    bindShortcut(shortcut, ...bindings) {
      shortcutManager.bindShortcut(shortcut, ...bindings);
    },

    createTitle(shortcutName, section) {
      const desc = shortcutManager.getDescription(section, shortcutName);
      const shortcut = shortcutManager.getShortcut(shortcutName);
      return (desc && shortcut) ? `${desc} (shortcut: ${shortcut})` : '';
    },

    _addOwnKeyBindings(shortcut, handler) {
      const bindings = shortcutManager.getBindingsForShortcut(shortcut);
      if (!bindings) {
        return;
      }
      if (bindings[0] === DOC_ONLY) {
        return;
      }
      if (bindings[0] === GO_KEY) {
        bindings.slice(1).forEach(binding =>
          this._shortcut_go_table.set(binding, handler));
      } else if (bindings[0] === V_KEY) {
        // for each binding added with the go/v key, we set the handler to be
        // handleVKeyAction. handleVKeyAction then looks up in th
        // shortcut_table to see what the relevant handler should be
        bindings.slice(1).forEach(binding =>
          this._shortcut_v_table.set(binding, handler));
      } else {
        this.addOwnKeyBinding(bindings.join(' '), handler);
      }
    },

    /** @override */
    attached() {
      const shortcuts = shortcutManager.attachHost(this);
      if (!shortcuts) { return; }

      for (const key of Object.keys(shortcuts)) {
        this._addOwnKeyBindings(key, shortcuts[key]);
      }

      // each component that uses this behaviour must be aware if go key is
      // pressed or not, since it needs to check it as a modifier
      this.addOwnKeyBinding('g:keydown', '_handleGoKeyDown');
      this.addOwnKeyBinding('g:keyup', '_handleGoKeyUp');

      // If any of the shortcuts utilized GO_KEY, then they are handled
      // directly by this behavior.
      if (this._shortcut_go_table.size > 0) {
        this._shortcut_go_table.forEach((handler, key) => {
          this.addOwnKeyBinding(key, '_handleGoAction');
        });
      }

      this.addOwnKeyBinding('v:keydown', '_handleVKeyDown');
      this.addOwnKeyBinding('v:keyup', '_handleVKeyUp');
      if (this._shortcut_v_table.size > 0) {
        this._shortcut_v_table.forEach((handler, key) => {
          this.addOwnKeyBinding(key, '_handleVAction');
        });
      }
    },

    /** @override */
    detached() {
      if (shortcutManager.detachHost(this)) {
        this.removeOwnKeyBindings();
      }
    },

    keyboardShortcuts() {
      return {};
    },

    addKeyboardShortcutDirectoryListener(listener) {
      shortcutManager.addListener(listener);
    },

    removeKeyboardShortcutDirectoryListener(listener) {
      shortcutManager.removeListener(listener);
    },

    _handleVKeyDown(e) {
      this._shortcut_v_key_last_pressed = Date.now();
    },

    _handleVKeyUp(e) {
      setTimeout(() => {
        this._shortcut_v_key_last_pressed = null;
      }, V_KEY_TIMEOUT_MS);
    },

    _inVKeyMode() {
      return this._shortcut_v_key_last_pressed &&
          (Date.now() - this._shortcut_v_key_last_pressed <=
              V_KEY_TIMEOUT_MS);
    },

    _handleVAction(e) {
      if (!this._inVKeyMode() ||
          !this._shortcut_v_table.has(e.detail.key) ||
          this.shouldSuppressKeyboardShortcut(e)) {
        return;
      }
      e.preventDefault();
      const handler = this._shortcut_v_table.get(e.detail.key);
      this[handler](e);
    },

    _handleGoKeyDown(e) {
      this._shortcut_go_key_last_pressed = Date.now();
    },

    _handleGoKeyUp(e) {
      // Set go_key_last_pressed to null `GO_KEY_TIMEOUT_MS` after keyup event
      // so that users can trigger `g + i` by pressing g and i quickly.
      setTimeout(() => {
        this._shortcut_go_key_last_pressed = null;
      }, GO_KEY_TIMEOUT_MS);
    },

    _inGoKeyMode() {
      return this._shortcut_go_key_last_pressed &&
          (Date.now() - this._shortcut_go_key_last_pressed <=
              GO_KEY_TIMEOUT_MS);
    },

    _handleGoAction(e) {
      if (!this._inGoKeyMode() ||
          !this._shortcut_go_table.has(e.detail.key) ||
          this.shouldSuppressKeyboardShortcut(e)) {
        return;
      }
      e.preventDefault();
      const handler = this._shortcut_go_table.get(e.detail.key);
      this[handler](e);
    },
  },
];

export const KeyboardShortcutBinder = {
  DOC_ONLY,
  GO_KEY,
  V_KEY,
  Shortcut,
  ShortcutManager,
  ShortcutSection,

  bindShortcut(shortcut, ...bindings) {
    shortcutManager.bindShortcut(shortcut, ...bindings);
  },
};

// TODO(dmfilippov) Remove the following lines with assignments
// Plugins can use the behavior because it was accessible with
// the global Gerrit... variable. To avoid breaking changes in plugins
// temporary assign global variables.
window.Gerrit = window.Gerrit || {};
window.Gerrit.KeyboardShortcutBehavior = KeyboardShortcutBehavior;
window.Gerrit.KeyboardShortcutBinder = KeyboardShortcutBinder;
