/**
 * @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 '../../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';
import {htmlTemplate} from './gr-router_html.js';
import {BaseUrlBehavior} from '../../../behaviors/base-url-behavior/base-url-behavior.js';
import {PatchSetBehavior} from '../../../behaviors/gr-patch-set-behavior/gr-patch-set-behavior.js';
import {URLEncodingBehavior} from '../../../behaviors/gr-url-encoding-behavior/gr-url-encoding-behavior.js';
import {GerritNav} from '../gr-navigation/gr-navigation.js';

const RoutePattern = {
  ROOT: '/',

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

  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.
// If you move this code to other place, please update comment about
// gr-router and gr-app in the PolyGerritIndexHtml.soy file if needed
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');
  });
})();

/**
 * @extends Polymer.Element
 */
class GrRouter extends mixinBehaviors( [
  BaseUrlBehavior,
  PatchSetBehavior,
  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 = GerritNav.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 GerritNav.WeblinkType.FILE:
        return this._getFileWebLinks(params);
      case GerritNav.WeblinkType.CHANGE:
        return this._getChangeWeblinks(params);
      case GerritNav.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 === GerritNav.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 === GerritNav.GroupDetailView.MEMBERS) {
      url += ',members';
    } else if (params.detail === GerritNav.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 === GerritNav.RepoDetailView.ACCESS) {
      url += ',access';
    } else if (params.detail === GerritNav.RepoDetailView.BRANCHES) {
      url += ',branches';
    } else if (params.detail === GerritNav.RepoDetailView.TAGS) {
      url += ',tags';
    } else if (params.detail === GerritNav.RepoDetailView.COMMANDS) {
      url += ',commands';
    } else if (params.detail === GerritNav.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(); });
  }

  /**  Page.js middleware that try parse the querystring into queryMap. */
  _queryStringMiddleware(ctx, next) {
    let queryMap = new Map();
    if (ctx.querystring) {
      // https://caniuse.com/#search=URLSearchParams
      if (window.URLSearchParams) {
        queryMap = new URLSearchParams(ctx.querystring);
      } else {
        queryMap = new Map(this._parseQueryString(ctx.querystring));
      }
    }
    ctx.queryMap = queryMap;
    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,
        (ctx, next) => this._loadUserMiddleware(ctx, next),
        (ctx, next) => this._queryStringMiddleware(ctx, next),
        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);
    }

    GerritNav.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.dispatchEvent(new CustomEvent('location-change', {
          detail: {
            hash: window.location.hash,
            pathname: window.location.pathname,
          },
          composed: true, bubbles: true,
        }));
      }, 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.LEGACY_PROJECT_DASHBOARD,
        '_handleLegacyProjectDashboardRoute');

    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+-is:wip');
      }
    });
  }

  /**
   * 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: GerritNav.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: GerritNav.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: GerritNav.View.DASHBOARD,
      project,
      dashboard: decodeURIComponent(data.params[1]),
    });
    this.$.reporting.setRepoName(project);
  }

  _handleLegacyProjectDashboardRoute(data) {
    this._redirect('/p/' + data.params[0] + '/+/dashboard/' + data.params[1]);
  }

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

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

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

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

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

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

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

  _handleGroupListFilterRoute(data) {
    this._setParams({
      view: GerritNav.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: GerritNav.View.REPO,
      detail: GerritNav.RepoDetailView.COMMANDS,
      repo,
    });
    this.$.reporting.setRepoName(repo);
  }

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

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

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

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

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

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

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

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

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

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

  _handleRepoListFilterRoute(data) {
    this._setParams({
      view: GerritNav.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: GerritNav.View.REPO,
      repo,
    });
    this.$.reporting.setRepoName(repo);
  }

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

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

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

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

  _handleQueryRoute(data) {
    this._setParams({
      view: GerritNav.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: GerritNav.View.CHANGE,
      queryMap: ctx.queryMap,
    };

    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: GerritNav.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: GerritNav.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: GerritNav.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: GerritNav.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: GerritNav.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 = GerritNav.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: GerritNav.View.SETTINGS,
      emailToken: token,
    });
  }

  _handleSettingsRoute(data) {
    this._setParams({view: GerritNav.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 = GerritNav.View.PLUGIN_SCREEN;
    const plugin = ctx.params[0];
    const screen = ctx.params[1];
    this._setParams({view, plugin, screen});
  }

  _handleDocumentationSearchRoute(data) {
    this._setParams({
      view: GerritNav.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);
