/**
 * @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.
 */
import '../../../scripts/bundled-polymer.js';

import '../../../behaviors/base-url-behavior/base-url-behavior.js';
import '../../../behaviors/fire-behavior/fire-behavior.js';
import '../../../behaviors/gr-patch-set-behavior/gr-patch-set-behavior.js';
import '../../../behaviors/gr-url-encoding-behavior/gr-url-encoding-behavior.js';
import '../gr-navigation/gr-navigation.js';
import '../../shared/gr-rest-api-interface/gr-rest-api-interface.js';
import '../gr-reporting/gr-reporting.js';
import {mixinBehaviors} from '@polymer/polymer/lib/legacy/class.js';
import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin.js';
import {PolymerElement} from '@polymer/polymer/polymer-element.js';
import page from 'page/page.mjs';
self.page = page;
import {htmlTemplate} from './gr-router_html.js';

const RoutePattern = {
  ROOT: '/',

  DASHBOARD: /^\/dashboard\/(.+)$/,
  CUSTOM_DASHBOARD: /^\/dashboard\/?$/,
  PROJECT_DASHBOARD: /^\/p\/(.+)\/\+\/dashboard\/(.+)/,

  AGREEMENTS: /^\/settings\/agreements\/?/,
  NEW_AGREEMENTS: /^\/settings\/new-agreement\/?/,
  REGISTER: /^\/register(\/.*)?$/,

  // Pattern for login and logout URLs intended to be passed-through. May
  // include a return URL.
  LOG_IN_OR_OUT: /\/log(in|out)(\/(.+))?$/,

  // Pattern for a catchall route when no other pattern is matched.
  DEFAULT: /.*/,

  // Matches /admin/groups/[uuid-]<group>
  GROUP: /^\/admin\/groups\/(?:uuid-)?([^,]+)$/,

  // Redirects /groups/self to /settings/#Groups for GWT compatibility
  GROUP_SELF: /^\/groups\/self/,

  // Matches /admin/groups/[uuid-]<group>,info (backwords compat with gwtui)
  // Redirects to /admin/groups/[uuid-]<group>
  GROUP_INFO: /^\/admin\/groups\/(?:uuid-)?(.+),info$/,

  // Matches /admin/groups/<group>,audit-log
  GROUP_AUDIT_LOG: /^\/admin\/groups\/(?:uuid-)?(.+),audit-log$/,

  // Matches /admin/groups/[uuid-]<group>,members
  GROUP_MEMBERS: /^\/admin\/groups\/(?:uuid-)?(.+),members$/,

  // Matches /admin/groups[,<offset>][/].
  GROUP_LIST_OFFSET: /^\/admin\/groups(,(\d+))?(\/)?$/,
  GROUP_LIST_FILTER: '/admin/groups/q/filter::filter',
  GROUP_LIST_FILTER_OFFSET: '/admin/groups/q/filter::filter,:offset',

  // Matches /admin/create-project
  LEGACY_CREATE_PROJECT: /^\/admin\/create-project\/?$/,

  // Matches /admin/create-project
  LEGACY_CREATE_GROUP: /^\/admin\/create-group\/?$/,

  PROJECT_OLD: /^\/admin\/(projects)\/?(.+)?$/,

  // Matches /admin/repos/<repo>
  REPO: /^\/admin\/repos\/([^,]+)$/,

  // Matches /admin/repos/<repo>,commands.
  REPO_COMMANDS: /^\/admin\/repos\/(.+),commands$/,

  // Matches /admin/repos/<repos>,access.
  REPO_ACCESS: /^\/admin\/repos\/(.+),access$/,

  // Matches /admin/repos/<repos>,access.
  REPO_DASHBOARDS: /^\/admin\/repos\/(.+),dashboards$/,

  // Matches /admin/repos[,<offset>][/].
  REPO_LIST_OFFSET: /^\/admin\/repos(,(\d+))?(\/)?$/,
  REPO_LIST_FILTER: '/admin/repos/q/filter::filter',
  REPO_LIST_FILTER_OFFSET: '/admin/repos/q/filter::filter,:offset',

  // Matches /admin/repos/<repo>,branches[,<offset>].
  BRANCH_LIST_OFFSET: /^\/admin\/repos\/(.+),branches(,(.+))?$/,
  BRANCH_LIST_FILTER: '/admin/repos/:repo,branches/q/filter::filter',
  BRANCH_LIST_FILTER_OFFSET:
      '/admin/repos/:repo,branches/q/filter::filter,:offset',

  // Matches /admin/repos/<repo>,tags[,<offset>].
  TAG_LIST_OFFSET: /^\/admin\/repos\/(.+),tags(,(.+))?$/,
  TAG_LIST_FILTER: '/admin/repos/:repo,tags/q/filter::filter',
  TAG_LIST_FILTER_OFFSET:
      '/admin/repos/:repo,tags/q/filter::filter,:offset',

  PLUGINS: /^\/plugins\/(.+)$/,

  PLUGIN_LIST: /^\/admin\/plugins(\/)?$/,

  // Matches /admin/plugins[,<offset>][/].
  PLUGIN_LIST_OFFSET: /^\/admin\/plugins(,(\d+))?(\/)?$/,
  PLUGIN_LIST_FILTER: '/admin/plugins/q/filter::filter',
  PLUGIN_LIST_FILTER_OFFSET: '/admin/plugins/q/filter::filter,:offset',

  QUERY: /^\/q\/([^,]+)(,(\d+))?$/,

  /**
   * Support vestigial params from GWT UI.
   *
   * @see Issue 7673.
   * @type {!RegExp}
   */
  QUERY_LEGACY_SUFFIX: /^\/q\/.+,n,z$/,

  // Matches /c/<changeNum>/[<basePatchNum>..][<patchNum>][/].
  CHANGE_LEGACY: /^\/c\/(\d+)\/?(((-?\d+|edit)(\.\.(\d+|edit))?))?\/?$/,
  CHANGE_NUMBER_LEGACY: /^\/(\d+)\/?/,

  // Matches
  // /c/<project>/+/<changeNum>/[<basePatchNum|edit>..][<patchNum|edit>].
  // TODO(kaspern): Migrate completely to project based URLs, with backwards
  // compatibility for change-only.
  CHANGE: /^\/c\/(.+)\/\+\/(\d+)(\/?((-?\d+|edit)(\.\.(\d+|edit))?))?\/?$/,

  // Matches /c/<project>/+/<changeNum>/[<patchNum|edit>],edit
  CHANGE_EDIT: /^\/c\/(.+)\/\+\/(\d+)(\/(\d+))?,edit\/?$/,

  // Matches
  // /c/<project>/+/<changeNum>/[<basePatchNum|edit>..]<patchNum|edit>/<path>.
  // TODO(kaspern): Migrate completely to project based URLs, with backwards
  // compatibility for change-only.
  // eslint-disable-next-line max-len
  DIFF: /^\/c\/(.+)\/\+\/(\d+)(\/((-?\d+|edit)(\.\.(\d+|edit))?(\/(.+))))\/?$/,

  // Matches /c/<project>/+/<changeNum>/[<patchNum|edit>]/<path>,edit[#lineNum]
  DIFF_EDIT: /^\/c\/(.+)\/\+\/(\d+)\/(\d+|edit)\/(.+),edit(\#\d+)?$/,

  // Matches non-project-relative
  // /c/<changeNum>/[<basePatchNum>..]<patchNum>/<path>.
  DIFF_LEGACY: /^\/c\/(\d+)\/((-?\d+|edit)(\.\.(\d+|edit))?)\/(.+)/,

  // Matches diff routes using @\d+ to specify a file name (whether or not
  // the project name is included).
  // eslint-disable-next-line max-len
  DIFF_LEGACY_LINENUM: /^\/c\/((.+)\/\+\/)?(\d+)(\/?((-?\d+|edit)(\.\.(\d+|edit))?\/(.+))?)@[ab]?\d+$/,

  SETTINGS: /^\/settings\/?/,
  SETTINGS_LEGACY: /^\/settings\/VE\/(\S+)/,

  // Matches /c/<changeNum>/ /<URL tail>
  // Catches improperly encoded URLs (context: Issue 7100)
  IMPROPERLY_ENCODED_PLUS: /^\/c\/(.+)\/\ \/(.+)$/,

  PLUGIN_SCREEN: /^\/x\/([\w-]+)\/([\w-]+)\/?/,

  DOCUMENTATION_SEARCH_FILTER: '/Documentation/q/filter::filter',
  DOCUMENTATION_SEARCH: /^\/Documentation\/q\/(.*)$/,
  DOCUMENTATION: /^\/Documentation(\/)?(.+)?/,
};

/**
 * Pattern to recognize and parse the diff line locations as they appear in
 * the hash of diff URLs. In this format, a number on its own indicates that
 * line number in the revision of the diff. A number prefixed by either an 'a'
 * or a 'b' indicates that line number of the base of the diff.
 *
 * @type {RegExp}
 */
const LINE_ADDRESS_PATTERN = /^([ab]?)(\d+)$/;

/**
 * Pattern to recognize '+' in url-encoded strings for replacement with ' '.
 */
const PLUS_PATTERN = /\+/g;

/**
 * Pattern to recognize leading '?' in window.location.search, for stripping.
 */
const QUESTION_PATTERN = /^\?*/;

/**
 * GWT UI would use @\d+ at the end of a path to indicate linenum.
 */
const LEGACY_LINENUM_PATTERN = /@([ab]?\d+)$/;

const LEGACY_QUERY_SUFFIX_PATTERN = /,n,z$/;

const REPO_TOKEN_PATTERN = /\$\{(project|repo)\}/g;

// Polymer makes `app` intrinsically defined on the window by virtue of the
// custom element having the id "app", but it is made explicit here.
const app = document.querySelector('#app');
if (!app) {
  console.log('No gr-app found (running tests)');
}

// Setup listeners outside of the router component initialization.
(function() {
  const reporting = document.createElement('gr-reporting');

  window.addEventListener('WebComponentsReady', () => {
    reporting.timeEnd('WebComponentsReady');
  });
})();

/**
 * @appliesMixin Gerrit.BaseUrlMixin
 * @appliesMixin Gerrit.FireMixin
 * @appliesMixin Gerrit.PatchSetMixin
 * @appliesMixin Gerrit.URLEncodingMixin
 * @extends Polymer.Element
 */
class GrRouter extends mixinBehaviors( [
  Gerrit.BaseUrlBehavior,
  Gerrit.FireBehavior,
  Gerrit.PatchSetBehavior,
  Gerrit.URLEncodingBehavior,
], GestureEventListeners(
    LegacyElementMixin(
        PolymerElement))) {
  static get template() { return htmlTemplate; }

  static get is() { return 'gr-router'; }

  static get properties() {
    return {
      _app: {
        type: Object,
        value: app,
      },
      _isRedirecting: Boolean,
      // This variable is to differentiate between internal navigation (false)
      // and for first navigation in app after loaded from server (true).
      _isInitialLoad: {
        type: Boolean,
        value: true,
      },
    };
  }

  start() {
    if (!this._app) { return; }
    this._startRouter();
  }

  _setParams(params) {
    this._appElement().params = params;
  }

  _appElement() {
    // In Polymer2 you have to reach through the shadow root of the app
    // element. This obviously breaks encapsulation.
    // TODO(brohlfs): Make this more elegant, e.g. by exposing app-element
    // explicitly in app, or by delegating to it.
    return document.getElementById('app-element') ||
        document.getElementById('app').shadowRoot.getElementById(
            'app-element');
  }

  _redirect(url) {
    this._isRedirecting = true;
    page.redirect(url);
  }

  /**
   * @param {!Object} params
   * @return {string}
   */
  _generateUrl(params) {
    const base = this.getBaseUrl();
    let url = '';
    const Views = Gerrit.Nav.View;

    if (params.view === Views.SEARCH) {
      url = this._generateSearchUrl(params);
    } else if (params.view === Views.CHANGE) {
      url = this._generateChangeUrl(params);
    } else if (params.view === Views.DASHBOARD) {
      url = this._generateDashboardUrl(params);
    } else if (params.view === Views.DIFF || params.view === Views.EDIT) {
      url = this._generateDiffOrEditUrl(params);
    } else if (params.view === Views.GROUP) {
      url = this._generateGroupUrl(params);
    } else if (params.view === Views.REPO) {
      url = this._generateRepoUrl(params);
    } else if (params.view === Views.ROOT) {
      url = '/';
    } else if (params.view === Views.SETTINGS) {
      url = this._generateSettingsUrl(params);
    } else {
      throw new Error('Can\'t generate');
    }

    return base + url;
  }

  _generateWeblinks(params) {
    const type = params.type;
    switch (type) {
      case Gerrit.Nav.WeblinkType.FILE:
        return this._getFileWebLinks(params);
      case Gerrit.Nav.WeblinkType.CHANGE:
        return this._getChangeWeblinks(params);
      case Gerrit.Nav.WeblinkType.PATCHSET:
        return this._getPatchSetWeblink(params);
      default:
        console.warn(`Unsupported weblink ${type}!`);
    }
  }

  _getPatchSetWeblink(params) {
    const {commit, options} = params;
    const {weblinks, config} = options || {};
    const name = commit && commit.slice(0, 7);
    const weblink = this._getBrowseCommitWeblink(weblinks, config);
    if (!weblink || !weblink.url) {
      return {name};
    } else {
      return {name, url: weblink.url};
    }
  }

  _firstCodeBrowserWeblink(weblinks) {
    // This is an ordered whitelist of web link types that provide direct
    // links to the commit in the url property.
    const codeBrowserLinks = ['gitiles', 'browse', 'gitweb'];
    for (let i = 0; i < codeBrowserLinks.length; i++) {
      const weblink =
        weblinks.find(weblink => weblink.name === codeBrowserLinks[i]);
      if (weblink) { return weblink; }
    }
    return null;
  }

  _getBrowseCommitWeblink(weblinks, config) {
    if (!weblinks) { return null; }
    let weblink;
    // Use primary weblink if configured and exists.
    if (config && config.gerrit && config.gerrit.primary_weblink_name) {
      weblink = weblinks.find(
          weblink => weblink.name === config.gerrit.primary_weblink_name
      );
    }
    if (!weblink) {
      weblink = this._firstCodeBrowserWeblink(weblinks);
    }
    if (!weblink) { return null; }
    return weblink;
  }

  _getChangeWeblinks({repo, commit, options: {weblinks, config}}) {
    if (!weblinks || !weblinks.length) return [];
    const commitWeblink = this._getBrowseCommitWeblink(weblinks, config);
    return weblinks.filter(weblink =>
      !commitWeblink ||
      !commitWeblink.name ||
      weblink.name !== commitWeblink.name);
  }

  _getFileWebLinks({repo, commit, file, options: {weblinks}}) {
    return weblinks;
  }

  /**
   * @param {!Object} params
   * @return {string}
   */
  _generateSearchUrl(params) {
    let offsetExpr = '';
    if (params.offset && params.offset > 0) {
      offsetExpr = ',' + params.offset;
    }

    if (params.query) {
      return '/q/' + this.encodeURL(params.query, true) + offsetExpr;
    }

    const operators = [];
    if (params.owner) {
      operators.push('owner:' + this.encodeURL(params.owner, false));
    }
    if (params.project) {
      operators.push('project:' + this.encodeURL(params.project, false));
    }
    if (params.branch) {
      operators.push('branch:' + this.encodeURL(params.branch, false));
    }
    if (params.topic) {
      operators.push('topic:"' + this.encodeURL(params.topic, false) + '"');
    }
    if (params.hashtag) {
      operators.push('hashtag:"' +
          this.encodeURL(params.hashtag.toLowerCase(), false) + '"');
    }
    if (params.statuses) {
      if (params.statuses.length === 1) {
        operators.push(
            'status:' + this.encodeURL(params.statuses[0], false));
      } else if (params.statuses.length > 1) {
        operators.push(
            '(' +
            params.statuses.map(s => `status:${this.encodeURL(s, false)}`)
                .join(' OR ') +
            ')');
      }
    }

    return '/q/' + operators.join('+') + offsetExpr;
  }

  /**
   * @param {!Object} params
   * @return {string}
   */
  _generateChangeUrl(params) {
    let range = this._getPatchRangeExpression(params);
    if (range.length) { range = '/' + range; }
    let suffix = `${range}`;
    if (params.querystring) {
      suffix += '?' + params.querystring;
    } else if (params.edit) {
      suffix += ',edit';
    }
    if (params.messageHash) {
      suffix += params.messageHash;
    }
    if (params.project) {
      const encodedProject = this.encodeURL(params.project, true);
      return `/c/${encodedProject}/+/${params.changeNum}${suffix}`;
    } else {
      return `/c/${params.changeNum}${suffix}`;
    }
  }

  /**
   * @param {!Object} params
   * @return {string}
   */
  _generateDashboardUrl(params) {
    const repoName = params.repo || params.project || null;
    if (params.sections) {
      // Custom dashboard.
      const queryParams = this._sectionsToEncodedParams(params.sections,
          repoName);
      if (params.title) {
        queryParams.push('title=' + encodeURIComponent(params.title));
      }
      const user = params.user ? params.user : '';
      return `/dashboard/${user}?${queryParams.join('&')}`;
    } else if (repoName) {
      // Project dashboard.
      const encodedRepo = this.encodeURL(repoName, true);
      return `/p/${encodedRepo}/+/dashboard/${params.dashboard}`;
    } else {
      // User dashboard.
      return `/dashboard/${params.user || 'self'}`;
    }
  }

  /**
   * @param {!Array<!{name: string, query: string}>} sections
   * @param {string=} opt_repoName
   * @return {!Array<string>}
   */
  _sectionsToEncodedParams(sections, opt_repoName) {
    return sections.map(section => {
      // If there is a repo name provided, make sure to substitute it into the
      // ${repo} (or legacy ${project}) query tokens.
      const query = opt_repoName ?
        section.query.replace(REPO_TOKEN_PATTERN, opt_repoName) :
        section.query;
      return encodeURIComponent(section.name) + '=' +
          encodeURIComponent(query);
    });
  }

  /**
   * @param {!Object} params
   * @return {string}
   */
  _generateDiffOrEditUrl(params) {
    let range = this._getPatchRangeExpression(params);
    if (range.length) { range = '/' + range; }

    let suffix = `${range}/${this.encodeURL(params.path, true)}`;

    if (params.view === Gerrit.Nav.View.EDIT) { suffix += ',edit'; }

    if (params.lineNum) {
      suffix += '#';
      if (params.leftSide) { suffix += 'b'; }
      suffix += params.lineNum;
    }

    if (params.project) {
      const encodedProject = this.encodeURL(params.project, true);
      return `/c/${encodedProject}/+/${params.changeNum}${suffix}`;
    } else {
      return `/c/${params.changeNum}${suffix}`;
    }
  }

  /**
   * @param {!Object} params
   * @return {string}
   */
  _generateGroupUrl(params) {
    let url = `/admin/groups/${this.encodeURL(params.groupId + '', true)}`;
    if (params.detail === Gerrit.Nav.GroupDetailView.MEMBERS) {
      url += ',members';
    } else if (params.detail === Gerrit.Nav.GroupDetailView.LOG) {
      url += ',audit-log';
    }
    return url;
  }

  /**
   * @param {!Object} params
   * @return {string}
   */
  _generateRepoUrl(params) {
    let url = `/admin/repos/${this.encodeURL(params.repoName + '', true)}`;
    if (params.detail === Gerrit.Nav.RepoDetailView.ACCESS) {
      url += ',access';
    } else if (params.detail === Gerrit.Nav.RepoDetailView.BRANCHES) {
      url += ',branches';
    } else if (params.detail === Gerrit.Nav.RepoDetailView.TAGS) {
      url += ',tags';
    } else if (params.detail === Gerrit.Nav.RepoDetailView.COMMANDS) {
      url += ',commands';
    } else if (params.detail === Gerrit.Nav.RepoDetailView.DASHBOARDS) {
      url += ',dashboards';
    }
    return url;
  }

  /**
   * @param {!Object} params
   * @return {string}
   */
  _generateSettingsUrl(params) {
    return '/settings';
  }

  /**
   * Given an object of parameters, potentially including a `patchNum` or a
   * `basePatchNum` or both, return a string representation of that range. If
   * no range is indicated in the params, the empty string is returned.
   *
   * @param {!Object} params
   * @return {string}
   */
  _getPatchRangeExpression(params) {
    let range = '';
    if (params.patchNum) { range = '' + params.patchNum; }
    if (params.basePatchNum) { range = params.basePatchNum + '..' + range; }
    return range;
  }

  /**
   * Given a set of params without a project, gets the project from the rest
   * API project lookup and then sets the app params.
   *
   * @param {?Object} params
   */
  _normalizeLegacyRouteParams(params) {
    if (!params.changeNum) { return Promise.resolve(); }

    return this.$.restAPI.getFromProjectLookup(params.changeNum)
        .then(project => {
          // Show a 404 and terminate if the lookup request failed. Attempting
          // to redirect after failing to get the project loops infinitely.
          if (!project) {
            this._show404();
            return;
          }

          params.project = project;
          this._normalizePatchRangeParams(params);
          this._redirect(this._generateUrl(params));
        });
  }

  /**
   * Normalizes the params object, and determines if the URL needs to be
   * modified to fit the proper schema.
   *
   * @param {*} params
   * @return {boolean} whether or not the URL needs to be upgraded.
   */
  _normalizePatchRangeParams(params) {
    const hasBasePatchNum = params.basePatchNum !== null &&
        params.basePatchNum !== undefined;
    const hasPatchNum = params.patchNum !== null &&
        params.patchNum !== undefined;
    let needsRedirect = false;

    // Diffing a patch against itself is invalid, so if the base and revision
    // patches are equal clear the base.
    if (hasBasePatchNum &&
        this.patchNumEquals(params.basePatchNum, params.patchNum)) {
      needsRedirect = true;
      params.basePatchNum = null;
    } else if (hasBasePatchNum && !hasPatchNum) {
      // Regexes set basePatchNum instead of patchNum when only one is
      // specified. Redirect is not needed in this case.
      params.patchNum = params.basePatchNum;
      params.basePatchNum = null;
    }
    return needsRedirect;
  }

  /**
   * Redirect the user to login using the given return-URL for redirection
   * after authentication success.
   *
   * @param {string} returnUrl
   */
  _redirectToLogin(returnUrl) {
    const basePath = this.getBaseUrl() || '';
    page(
        '/login/' + encodeURIComponent(returnUrl.substring(basePath.length)));
  }

  /**
   * Hashes parsed by page.js exclude "inner" hashes, so a URL like "/a#b#c"
   * is parsed to have a hash of "b" rather than "b#c". Instead, this method
   * parses hashes correctly. Will return an empty string if there is no hash.
   *
   * @param {!string} canonicalPath
   * @return {!string} Everything after the first '#' ("a#b#c" -> "b#c").
   */
  _getHashFromCanonicalPath(canonicalPath) {
    return canonicalPath.split('#').slice(1)
        .join('#');
  }

  _parseLineAddress(hash) {
    const match = hash.match(LINE_ADDRESS_PATTERN);
    if (!match) { return null; }
    return {
      leftSide: !!match[1],
      lineNum: parseInt(match[2], 10),
    };
  }

  /**
   * Check to see if the user is logged in and return a promise that only
   * resolves if the user is logged in. If the user us not logged in, the
   * promise is rejected and the page is redirected to the login flow.
   *
   * @param {!Object} data The parsed route data.
   * @return {!Promise<!Object>} A promise yielding the original route data
   *     (if it resolves).
   */
  _redirectIfNotLoggedIn(data) {
    return this.$.restAPI.getLoggedIn().then(loggedIn => {
      if (loggedIn) {
        return Promise.resolve();
      } else {
        this._redirectToLogin(data.canonicalPath);
        return Promise.reject(new Error());
      }
    });
  }

  /**  Page.js middleware that warms the REST API's logged-in cache line. */
  _loadUserMiddleware(ctx, next) {
    this.$.restAPI.getLoggedIn().then(() => { next(); });
  }

  /**
   * Map a route to a method on the router.
   *
   * @param {!string|!RegExp} pattern The page.js pattern for the route.
   * @param {!string} handlerName The method name for the handler. If the
   *     route is matched, the handler will be executed with `this` referring
   *     to the component. Its return value will be discarded so that it does
   *     not interfere with page.js.
   * @param  {?boolean=} opt_authRedirect If true, then auth is checked before
   *     executing the handler. If the user is not logged in, it will redirect
   *     to the login flow and the handler will not be executed. The login
   *     redirect specifies the matched URL to be used after successfull auth.
   */
  _mapRoute(pattern, handlerName, opt_authRedirect) {
    if (!this[handlerName]) {
      console.error('Attempted to map route to unknown method: ',
          handlerName);
      return;
    }
    page(pattern, this._loadUserMiddleware.bind(this), data => {
      this.$.reporting.locationChanged(handlerName);
      const promise = opt_authRedirect ?
        this._redirectIfNotLoggedIn(data) : Promise.resolve();
      promise.then(() => { this[handlerName](data); });
    });
  }

  _startRouter() {
    const base = this.getBaseUrl();
    if (base) {
      page.base(base);
    }

    Gerrit.Nav.setup(
        url => { page.show(url); },
        this._generateUrl.bind(this),
        params => this._generateWeblinks(params),
        x => x
    );

    page.exit('*', (ctx, next) => {
      if (!this._isRedirecting) {
        this.$.reporting.beforeLocationChanged();
      }
      this._isRedirecting = false;
      this._isInitialLoad = false;
      next();
    });

    // Middleware
    page((ctx, next) => {
      document.body.scrollTop = 0;

      if (ctx.hash.match(RoutePattern.PLUGIN_SCREEN)) {
        // Redirect all urls using hash #/x/plugin/screen to /x/plugin/screen
        // This is needed to allow plugins to add basic #/x/ screen links to
        // any location.
        this._redirect(ctx.hash);
        return;
      }

      // Fire asynchronously so that the URL is changed by the time the event
      // is processed.
      this.async(() => {
        this.fire('location-change', {
          hash: window.location.hash,
          pathname: window.location.pathname,
        });
      }, 1);
      next();
    });

    this._mapRoute(RoutePattern.ROOT, '_handleRootRoute');

    this._mapRoute(RoutePattern.DASHBOARD, '_handleDashboardRoute');

    this._mapRoute(RoutePattern.CUSTOM_DASHBOARD,
        '_handleCustomDashboardRoute');

    this._mapRoute(RoutePattern.PROJECT_DASHBOARD,
        '_handleProjectDashboardRoute');

    this._mapRoute(RoutePattern.GROUP_INFO, '_handleGroupInfoRoute', true);

    this._mapRoute(RoutePattern.GROUP_AUDIT_LOG, '_handleGroupAuditLogRoute',
        true);

    this._mapRoute(RoutePattern.GROUP_MEMBERS, '_handleGroupMembersRoute',
        true);

    this._mapRoute(RoutePattern.GROUP_LIST_OFFSET,
        '_handleGroupListOffsetRoute', true);

    this._mapRoute(RoutePattern.GROUP_LIST_FILTER_OFFSET,
        '_handleGroupListFilterOffsetRoute', true);

    this._mapRoute(RoutePattern.GROUP_LIST_FILTER,
        '_handleGroupListFilterRoute', true);

    this._mapRoute(RoutePattern.GROUP_SELF, '_handleGroupSelfRedirectRoute',
        true);

    this._mapRoute(RoutePattern.GROUP, '_handleGroupRoute', true);

    this._mapRoute(RoutePattern.PROJECT_OLD,
        '_handleProjectsOldRoute');

    this._mapRoute(RoutePattern.REPO_COMMANDS,
        '_handleRepoCommandsRoute', true);

    this._mapRoute(RoutePattern.REPO_ACCESS,
        '_handleRepoAccessRoute');

    this._mapRoute(RoutePattern.REPO_DASHBOARDS,
        '_handleRepoDashboardsRoute');

    this._mapRoute(RoutePattern.BRANCH_LIST_OFFSET,
        '_handleBranchListOffsetRoute');

    this._mapRoute(RoutePattern.BRANCH_LIST_FILTER_OFFSET,
        '_handleBranchListFilterOffsetRoute');

    this._mapRoute(RoutePattern.BRANCH_LIST_FILTER,
        '_handleBranchListFilterRoute');

    this._mapRoute(RoutePattern.TAG_LIST_OFFSET,
        '_handleTagListOffsetRoute');

    this._mapRoute(RoutePattern.TAG_LIST_FILTER_OFFSET,
        '_handleTagListFilterOffsetRoute');

    this._mapRoute(RoutePattern.TAG_LIST_FILTER,
        '_handleTagListFilterRoute');

    this._mapRoute(RoutePattern.LEGACY_CREATE_GROUP,
        '_handleCreateGroupRoute', true);

    this._mapRoute(RoutePattern.LEGACY_CREATE_PROJECT,
        '_handleCreateProjectRoute', true);

    this._mapRoute(RoutePattern.REPO_LIST_OFFSET,
        '_handleRepoListOffsetRoute');

    this._mapRoute(RoutePattern.REPO_LIST_FILTER_OFFSET,
        '_handleRepoListFilterOffsetRoute');

    this._mapRoute(RoutePattern.REPO_LIST_FILTER,
        '_handleRepoListFilterRoute');

    this._mapRoute(RoutePattern.REPO, '_handleRepoRoute');

    this._mapRoute(RoutePattern.PLUGINS, '_handlePassThroughRoute');

    this._mapRoute(RoutePattern.PLUGIN_LIST_OFFSET,
        '_handlePluginListOffsetRoute', true);

    this._mapRoute(RoutePattern.PLUGIN_LIST_FILTER_OFFSET,
        '_handlePluginListFilterOffsetRoute', true);

    this._mapRoute(RoutePattern.PLUGIN_LIST_FILTER,
        '_handlePluginListFilterRoute', true);

    this._mapRoute(RoutePattern.PLUGIN_LIST, '_handlePluginListRoute', true);

    this._mapRoute(RoutePattern.QUERY_LEGACY_SUFFIX,
        '_handleQueryLegacySuffixRoute');

    this._mapRoute(RoutePattern.QUERY, '_handleQueryRoute');

    this._mapRoute(RoutePattern.DIFF_LEGACY_LINENUM, '_handleLegacyLinenum');

    this._mapRoute(RoutePattern.CHANGE_NUMBER_LEGACY,
        '_handleChangeNumberLegacyRoute');

    this._mapRoute(RoutePattern.DIFF_EDIT, '_handleDiffEditRoute', true);

    this._mapRoute(RoutePattern.CHANGE_EDIT, '_handleChangeEditRoute', true);

    this._mapRoute(RoutePattern.DIFF, '_handleDiffRoute');

    this._mapRoute(RoutePattern.CHANGE, '_handleChangeRoute');

    this._mapRoute(RoutePattern.CHANGE_LEGACY, '_handleChangeLegacyRoute');

    this._mapRoute(RoutePattern.DIFF_LEGACY, '_handleDiffLegacyRoute');

    this._mapRoute(RoutePattern.AGREEMENTS, '_handleAgreementsRoute', true);

    this._mapRoute(RoutePattern.NEW_AGREEMENTS, '_handleNewAgreementsRoute',
        true);

    this._mapRoute(RoutePattern.SETTINGS_LEGACY,
        '_handleSettingsLegacyRoute', true);

    this._mapRoute(RoutePattern.SETTINGS, '_handleSettingsRoute', true);

    this._mapRoute(RoutePattern.REGISTER, '_handleRegisterRoute');

    this._mapRoute(RoutePattern.LOG_IN_OR_OUT, '_handlePassThroughRoute');

    this._mapRoute(RoutePattern.IMPROPERLY_ENCODED_PLUS,
        '_handleImproperlyEncodedPlusRoute');

    this._mapRoute(RoutePattern.PLUGIN_SCREEN, '_handlePluginScreen');

    this._mapRoute(RoutePattern.DOCUMENTATION_SEARCH_FILTER,
        '_handleDocumentationSearchRoute');

    // redirects /Documentation/q/* to /Documentation/q/filter:*
    this._mapRoute(RoutePattern.DOCUMENTATION_SEARCH,
        '_handleDocumentationSearchRedirectRoute');

    // Makes sure /Documentation/* links work (doin't return 404)
    this._mapRoute(RoutePattern.DOCUMENTATION,
        '_handleDocumentationRedirectRoute');

    // Note: this route should appear last so it only catches URLs unmatched
    // by other patterns.
    this._mapRoute(RoutePattern.DEFAULT, '_handleDefaultRoute');

    page.start();
  }

  /**
   * @param {!Object} data
   * @return {Promise|null} if handling the route involves asynchrony, then a
   *     promise is returned. Otherwise, synchronous handling returns null.
   */
  _handleRootRoute(data) {
    if (data.querystring.match(/^closeAfterLogin/)) {
      // Close child window on redirect after login.
      window.close();
      return null;
    }
    let hash = this._getHashFromCanonicalPath(data.canonicalPath);
    // For backward compatibility with GWT links.
    if (hash) {
      // In certain login flows the server may redirect to a hash without
      // a leading slash, which page.js doesn't handle correctly.
      if (hash[0] !== '/') {
        hash = '/' + hash;
      }
      if (hash.includes('/ /') && data.canonicalPath.includes('/+/')) {
        // Path decodes all '+' to ' ' -- this breaks project-based URLs.
        // See Issue 6888.
        hash = hash.replace('/ /', '/+/');
      }
      const base = this.getBaseUrl();
      let newUrl = base + hash;
      if (hash.startsWith('/VE/')) {
        newUrl = base + '/settings' + hash;
      }
      this._redirect(newUrl);
      return null;
    }
    return this.$.restAPI.getLoggedIn().then(loggedIn => {
      if (loggedIn) {
        this._redirect('/dashboard/self');
      } else {
        this._redirect('/q/status:open');
      }
    });
  }

  /**
   * Decode an application/x-www-form-urlencoded string.
   *
   * @param {string} qs The application/x-www-form-urlencoded string.
   * @return {string} The decoded string.
   */
  _decodeQueryString(qs) {
    return decodeURIComponent(qs.replace(PLUS_PATTERN, ' '));
  }

  /**
   * Parse a query string (e.g. window.location.search) into an array of
   * name/value pairs.
   *
   * @param {string} qs The application/x-www-form-urlencoded query string.
   * @return {!Array<!Array<string>>} An array of name/value pairs, where each
   *     element is a 2-element array.
   */
  _parseQueryString(qs) {
    qs = qs.replace(QUESTION_PATTERN, '');
    if (!qs) {
      return [];
    }
    const params = [];
    qs.split('&').forEach(param => {
      const idx = param.indexOf('=');
      let name;
      let value;
      if (idx < 0) {
        name = this._decodeQueryString(param);
        value = '';
      } else {
        name = this._decodeQueryString(param.substring(0, idx));
        value = this._decodeQueryString(param.substring(idx + 1));
      }
      if (name) {
        params.push([name, value]);
      }
    });
    return params;
  }

  /**
   * Handle dashboard routes. These may be user, or project dashboards.
   *
   * @param {!Object} data The parsed route data.
   */
  _handleDashboardRoute(data) {
    // User dashboard. We require viewing user to be logged in, else we
    // redirect to login for self dashboard or simple owner search for
    // other user dashboard.
    return this.$.restAPI.getLoggedIn().then(loggedIn => {
      if (!loggedIn) {
        if (data.params[0].toLowerCase() === 'self') {
          this._redirectToLogin(data.canonicalPath);
        } else {
          this._redirect('/q/owner:' + encodeURIComponent(data.params[0]));
        }
      } else {
        this._setParams({
          view: Gerrit.Nav.View.DASHBOARD,
          user: data.params[0],
        });
      }
    });
  }

  /**
   * Handle custom dashboard routes.
   *
   * @param {!Object} data The parsed route data.
   * @param {string=} opt_qs Optional query string associated with the route.
   *     If not given, window.location.search is used. (Used by tests).
   */
  _handleCustomDashboardRoute(data, opt_qs) {
    // opt_qs may be provided by a test, and it may have a falsy value
    const qs = opt_qs !== undefined ? opt_qs : window.location.search;
    const queryParams = this._parseQueryString(qs);
    let title = 'Custom Dashboard';
    const titleParam = queryParams.find(
        elem => elem[0].toLowerCase() === 'title');
    if (titleParam) {
      title = titleParam[1];
    }
    // Dashboards support a foreach param which adds a base query to any
    // additional query.
    const forEachParam = queryParams.find(
        elem => elem[0].toLowerCase() === 'foreach');
    let forEachQuery = null;
    if (forEachParam) {
      forEachQuery = forEachParam[1];
    }
    const sectionParams = queryParams.filter(
        elem => elem[0] && elem[1] && elem[0].toLowerCase() !== 'title' &&
        elem[0].toLowerCase() !== 'foreach');
    const sections = sectionParams.map(elem => {
      const query = forEachQuery ? `${forEachQuery} ${elem[1]}` : elem[1];
      return {
        name: elem[0],
        query,
      };
    });

    if (sections.length > 0) {
      // Custom dashboard view.
      this._setParams({
        view: Gerrit.Nav.View.DASHBOARD,
        user: 'self',
        sections,
        title,
      });
      return Promise.resolve();
    }

    // Redirect /dashboard/ -> /dashboard/self.
    this._redirect('/dashboard/self');
    return Promise.resolve();
  }

  _handleProjectDashboardRoute(data) {
    const project = data.params[0];
    this._setParams({
      view: Gerrit.Nav.View.DASHBOARD,
      project,
      dashboard: decodeURIComponent(data.params[1]),
    });
    this.$.reporting.setRepoName(project);
  }

  _handleGroupInfoRoute(data) {
    this._redirect('/admin/groups/' + encodeURIComponent(data.params[0]));
  }

  _handleGroupSelfRedirectRoute(data) {
    this._redirect('/settings/#Groups');
  }

  _handleGroupRoute(data) {
    this._setParams({
      view: Gerrit.Nav.View.GROUP,
      groupId: data.params[0],
    });
  }

  _handleGroupAuditLogRoute(data) {
    this._setParams({
      view: Gerrit.Nav.View.GROUP,
      detail: Gerrit.Nav.GroupDetailView.LOG,
      groupId: data.params[0],
    });
  }

  _handleGroupMembersRoute(data) {
    this._setParams({
      view: Gerrit.Nav.View.GROUP,
      detail: Gerrit.Nav.GroupDetailView.MEMBERS,
      groupId: data.params[0],
    });
  }

  _handleGroupListOffsetRoute(data) {
    this._setParams({
      view: Gerrit.Nav.View.ADMIN,
      adminView: 'gr-admin-group-list',
      offset: data.params[1] || 0,
      filter: null,
      openCreateModal: data.hash === 'create',
    });
  }

  _handleGroupListFilterOffsetRoute(data) {
    this._setParams({
      view: Gerrit.Nav.View.ADMIN,
      adminView: 'gr-admin-group-list',
      offset: data.params.offset,
      filter: data.params.filter,
    });
  }

  _handleGroupListFilterRoute(data) {
    this._setParams({
      view: Gerrit.Nav.View.ADMIN,
      adminView: 'gr-admin-group-list',
      filter: data.params.filter || null,
    });
  }

  _handleProjectsOldRoute(data) {
    let params = '';
    if (data.params[1]) {
      params = encodeURIComponent(data.params[1]);
      if (data.params[1].includes(',')) {
        params =
            encodeURIComponent(data.params[1]).replace('%2C', ',');
      }
    }

    this._redirect(`/admin/repos/${params}`);
  }

  _handleRepoCommandsRoute(data) {
    const repo = data.params[0];
    this._setParams({
      view: Gerrit.Nav.View.REPO,
      detail: Gerrit.Nav.RepoDetailView.COMMANDS,
      repo,
    });
    this.$.reporting.setRepoName(repo);
  }

  _handleRepoAccessRoute(data) {
    const repo = data.params[0];
    this._setParams({
      view: Gerrit.Nav.View.REPO,
      detail: Gerrit.Nav.RepoDetailView.ACCESS,
      repo,
    });
    this.$.reporting.setRepoName(repo);
  }

  _handleRepoDashboardsRoute(data) {
    const repo = data.params[0];
    this._setParams({
      view: Gerrit.Nav.View.REPO,
      detail: Gerrit.Nav.RepoDetailView.DASHBOARDS,
      repo,
    });
    this.$.reporting.setRepoName(repo);
  }

  _handleBranchListOffsetRoute(data) {
    this._setParams({
      view: Gerrit.Nav.View.REPO,
      detail: Gerrit.Nav.RepoDetailView.BRANCHES,
      repo: data.params[0],
      offset: data.params[2] || 0,
      filter: null,
    });
  }

  _handleBranchListFilterOffsetRoute(data) {
    this._setParams({
      view: Gerrit.Nav.View.REPO,
      detail: Gerrit.Nav.RepoDetailView.BRANCHES,
      repo: data.params.repo,
      offset: data.params.offset,
      filter: data.params.filter,
    });
  }

  _handleBranchListFilterRoute(data) {
    this._setParams({
      view: Gerrit.Nav.View.REPO,
      detail: Gerrit.Nav.RepoDetailView.BRANCHES,
      repo: data.params.repo,
      filter: data.params.filter || null,
    });
  }

  _handleTagListOffsetRoute(data) {
    this._setParams({
      view: Gerrit.Nav.View.REPO,
      detail: Gerrit.Nav.RepoDetailView.TAGS,
      repo: data.params[0],
      offset: data.params[2] || 0,
      filter: null,
    });
  }

  _handleTagListFilterOffsetRoute(data) {
    this._setParams({
      view: Gerrit.Nav.View.REPO,
      detail: Gerrit.Nav.RepoDetailView.TAGS,
      repo: data.params.repo,
      offset: data.params.offset,
      filter: data.params.filter,
    });
  }

  _handleTagListFilterRoute(data) {
    this._setParams({
      view: Gerrit.Nav.View.REPO,
      detail: Gerrit.Nav.RepoDetailView.TAGS,
      repo: data.params.repo,
      filter: data.params.filter || null,
    });
  }

  _handleRepoListOffsetRoute(data) {
    this._setParams({
      view: Gerrit.Nav.View.ADMIN,
      adminView: 'gr-repo-list',
      offset: data.params[1] || 0,
      filter: null,
      openCreateModal: data.hash === 'create',
    });
  }

  _handleRepoListFilterOffsetRoute(data) {
    this._setParams({
      view: Gerrit.Nav.View.ADMIN,
      adminView: 'gr-repo-list',
      offset: data.params.offset,
      filter: data.params.filter,
    });
  }

  _handleRepoListFilterRoute(data) {
    this._setParams({
      view: Gerrit.Nav.View.ADMIN,
      adminView: 'gr-repo-list',
      filter: data.params.filter || null,
    });
  }

  _handleCreateProjectRoute(data) {
    // Redirects the legacy route to the new route, which displays the project
    // list with a hash 'create'.
    this._redirect('/admin/repos#create');
  }

  _handleCreateGroupRoute(data) {
    // Redirects the legacy route to the new route, which displays the group
    // list with a hash 'create'.
    this._redirect('/admin/groups#create');
  }

  _handleRepoRoute(data) {
    const repo = data.params[0];
    this._setParams({
      view: Gerrit.Nav.View.REPO,
      repo,
    });
    this.$.reporting.setRepoName(repo);
  }

  _handlePluginListOffsetRoute(data) {
    this._setParams({
      view: Gerrit.Nav.View.ADMIN,
      adminView: 'gr-plugin-list',
      offset: data.params[1] || 0,
      filter: null,
    });
  }

  _handlePluginListFilterOffsetRoute(data) {
    this._setParams({
      view: Gerrit.Nav.View.ADMIN,
      adminView: 'gr-plugin-list',
      offset: data.params.offset,
      filter: data.params.filter,
    });
  }

  _handlePluginListFilterRoute(data) {
    this._setParams({
      view: Gerrit.Nav.View.ADMIN,
      adminView: 'gr-plugin-list',
      filter: data.params.filter || null,
    });
  }

  _handlePluginListRoute(data) {
    this._setParams({
      view: Gerrit.Nav.View.ADMIN,
      adminView: 'gr-plugin-list',
    });
  }

  _handleQueryRoute(data) {
    this._setParams({
      view: Gerrit.Nav.View.SEARCH,
      query: data.params[0],
      offset: data.params[2],
    });
  }

  _handleQueryLegacySuffixRoute(ctx) {
    this._redirect(ctx.path.replace(LEGACY_QUERY_SUFFIX_PATTERN, ''));
  }

  _handleChangeNumberLegacyRoute(ctx) {
    this._redirect('/c/' + encodeURIComponent(ctx.params[0]));
  }

  _handleChangeRoute(ctx) {
    // Parameter order is based on the regex group number matched.
    const params = {
      project: ctx.params[0],
      changeNum: ctx.params[1],
      basePatchNum: ctx.params[4],
      patchNum: ctx.params[6],
      view: Gerrit.Nav.View.CHANGE,
    };

    this.$.reporting.setRepoName(params.project);
    this._redirectOrNavigate(params);
  }

  _handleDiffRoute(ctx) {
    // Parameter order is based on the regex group number matched.
    const params = {
      project: ctx.params[0],
      changeNum: ctx.params[1],
      basePatchNum: ctx.params[4],
      patchNum: ctx.params[6],
      path: ctx.params[8],
      view: Gerrit.Nav.View.DIFF,
    };

    const address = this._parseLineAddress(ctx.hash);
    if (address) {
      params.leftSide = address.leftSide;
      params.lineNum = address.lineNum;
    }
    this.$.reporting.setRepoName(params.project);
    this._redirectOrNavigate(params);
  }

  _handleChangeLegacyRoute(ctx) {
    // Parameter order is based on the regex group number matched.
    const params = {
      changeNum: ctx.params[0],
      basePatchNum: ctx.params[3],
      patchNum: ctx.params[5],
      view: Gerrit.Nav.View.CHANGE,
      querystring: ctx.querystring,
    };

    this._normalizeLegacyRouteParams(params);
  }

  _handleLegacyLinenum(ctx) {
    this._redirect(ctx.path.replace(LEGACY_LINENUM_PATTERN, '#$1'));
  }

  _handleDiffLegacyRoute(ctx) {
    // Parameter order is based on the regex group number matched.
    const params = {
      changeNum: ctx.params[0],
      basePatchNum: ctx.params[2],
      patchNum: ctx.params[4],
      path: ctx.params[5],
      view: Gerrit.Nav.View.DIFF,
    };

    const address = this._parseLineAddress(ctx.hash);
    if (address) {
      params.leftSide = address.leftSide;
      params.lineNum = address.lineNum;
    }

    this._normalizeLegacyRouteParams(params);
  }

  _handleDiffEditRoute(ctx) {
    // Parameter order is based on the regex group number matched.
    const project = ctx.params[0];
    this._redirectOrNavigate({
      project,
      changeNum: ctx.params[1],
      patchNum: ctx.params[2],
      path: ctx.params[3],
      lineNum: ctx.hash,
      view: Gerrit.Nav.View.EDIT,
    });
    this.$.reporting.setRepoName(project);
  }

  _handleChangeEditRoute(ctx) {
    // Parameter order is based on the regex group number matched.
    const project = ctx.params[0];
    this._redirectOrNavigate({
      project,
      changeNum: ctx.params[1],
      patchNum: ctx.params[3],
      view: Gerrit.Nav.View.CHANGE,
      edit: true,
    });
    this.$.reporting.setRepoName(project);
  }

  /**
   * Normalize the patch range params for a the change or diff view and
   * redirect if URL upgrade is needed.
   */
  _redirectOrNavigate(params) {
    const needsRedirect = this._normalizePatchRangeParams(params);
    if (needsRedirect) {
      this._redirect(this._generateUrl(params));
    } else {
      this._setParams(params);
    }
  }

  _handleAgreementsRoute() {
    this._redirect('/settings/#Agreements');
  }

  _handleNewAgreementsRoute(data) {
    data.params.view = Gerrit.Nav.View.AGREEMENTS;
    this._setParams(data.params);
  }

  _handleSettingsLegacyRoute(data) {
    // email tokens may contain '+' but no space.
    // The parameter parsing replaces all '+' with a space,
    // undo that to have valid tokens.
    const token = data.params[0].replace(/ /g, '+');
    this._setParams({
      view: Gerrit.Nav.View.SETTINGS,
      emailToken: token,
    });
  }

  _handleSettingsRoute(data) {
    this._setParams({view: Gerrit.Nav.View.SETTINGS});
  }

  _handleRegisterRoute(ctx) {
    this._setParams({justRegistered: true});
    let path = ctx.params[0] || '/';

    // Prevent redirect looping.
    if (path.startsWith('/register')) { path = '/'; }

    if (path[0] !== '/') { return; }
    this._redirect(this.getBaseUrl() + path);
  }

  /**
   * Handler for routes that should pass through the router and not be caught
   * by the catchall _handleDefaultRoute handler.
   */
  _handlePassThroughRoute() {
    location.reload();
  }

  /**
   * URL may sometimes have /+/ encoded to / /.
   * Context: Issue 6888, Issue 7100
   */
  _handleImproperlyEncodedPlusRoute(ctx) {
    let hash = this._getHashFromCanonicalPath(ctx.canonicalPath);
    if (hash.length) { hash = '#' + hash; }
    this._redirect(`/c/${ctx.params[0]}/+/${ctx.params[1]}${hash}`);
  }

  _handlePluginScreen(ctx) {
    const view = Gerrit.Nav.View.PLUGIN_SCREEN;
    const plugin = ctx.params[0];
    const screen = ctx.params[1];
    this._setParams({view, plugin, screen});
  }

  _handleDocumentationSearchRoute(data) {
    this._setParams({
      view: Gerrit.Nav.View.DOCUMENTATION_SEARCH,
      filter: data.params.filter || null,
    });
  }

  _handleDocumentationSearchRedirectRoute(data) {
    this._redirect('/Documentation/q/filter:' +
        encodeURIComponent(data.params[0]));
  }

  _handleDocumentationRedirectRoute(data) {
    if (data.params[1]) {
      location.reload();
    } else {
      // Redirect /Documentation to /Documentation/index.html
      this._redirect('/Documentation/index.html');
    }
  }

  /**
   * Catchall route for when no other route is matched.
   */
  _handleDefaultRoute() {
    if (this._isInitialLoad) {
      // Server recognized this route as polygerrit, so we show 404.
      this._show404();
    } else {
      // Route can be recognized by server, so we pass it to server.
      this._handlePassThroughRoute();
    }
  }

  _show404() {
    // Note: the app's 404 display is tightly-coupled with catching 404
    // network responses, so we simulate a 404 response status to display it.
    // TODO: Decouple the gr-app error view from network responses.
    this._appElement().dispatchEvent(new CustomEvent('page-error',
        {detail: {response: {status: 404}}}));
  }
}

customElements.define(GrRouter.is, GrRouter);
