/**
 * @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.
 */
(function() {
  'use strict';

  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-)?([^,]+)$/,

    // 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
    DIFF_EDIT: /^\/c\/(.+)\/\+\/(\d+)\/(\d+|edit)\/(.+),edit$/,

    // 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('load', () => {
      reporting.pageLoaded();
    });

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

  Polymer({
    is: 'gr-router',

    properties: {
      _app: {
        type: Object,
        value: app,
      },
      _isRedirecting: Boolean,
    },

    behaviors: [
      Gerrit.BaseUrlBehavior,
      Gerrit.PatchSetBehavior,
      Gerrit.URLEncodingBehavior,
    ],

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

    _setParams(params) {
      this._app.params = params;
    },

    _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 {repo, commit, options} = params;
      const {weblinks, config} = options || {};
      const name = commit && commit.slice(0, 7);
      const gitwebConfigUrl = this._configBasedCommitUrl(repo, commit, config);
      if (gitwebConfigUrl) {
        return {
          name,
          url: gitwebConfigUrl,
        };
      }
      const url = this._getSupportedWeblinkUrl(weblinks);
      if (!url) {
        return {name};
      } else {
        return {name, url};
      }
    },

    _configBasedCommitUrl(repo, commit, config) {
      if (config && config.gitweb && config.gitweb.url &&
          config.gitweb.type && config.gitweb.type.revision) {
        return config.gitweb.url + config.gitweb.type.revision
            .replace('${project}', repo)
            .replace('${commit}', commit);
      }
    },

    _isDirectCommit(link) {
      // This is a whitelist of web link types that provide direct links to
      // the commit in the url property.
      return link.name === 'gitiles' || link.name === 'gitweb';
    },

    _getSupportedWeblinkUrl(weblinks) {
      if (!weblinks) { return null; }
      const weblink = weblinks.find(this._isDirectCommit);
      if (!weblink) { return null; }
      return weblink.url;
    },

    _getChangeWeblinks({repo, commit, options: {weblinks}}) {
      if (!weblinks || !weblinks.length) return [];
      return weblinks.filter(weblink => !this._isDirectCommit(weblink)).map(
          ({name, url}) => {
            if (!url.startsWith('https:') && !url.startsWith('http:')) {
              url = this.getBaseUrl() + (url.startsWith('/') ? '' : '/') + url;
            }
            return {name, url};
          });
    },

    _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.
        return `/p/${repoName}/+/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;
      }
      // In GWTUI, edits are represented in URLs with either 0 or 'edit'.
      // TODO(kaspern): Remove this normalization when GWT UI is gone.
      if (this.patchNumEquals(params.basePatchNum, 0)) {
        params.basePatchNum = this.EDIT_NAME;
        needsRedirect = true;
      }
      if (this.patchNumEquals(params.patchNum, 0)) {
        params.patchNum = this.EDIT_NAME;
        needsRedirect = true;
      }
      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();
        }
      });
    },

    /**  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;
        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, '_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) {
      this._setParams({
        view: Gerrit.Nav.View.DASHBOARD,
        project: data.params[0],
        dashboard: decodeURIComponent(data.params[1]),
      });
    },

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

    _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) {
      if (data.params[1]) {
        this._redirect('/admin/repos/' + encodeURIComponent(data.params[1]));
      } else {
        this._redirect('/admin/repos');
      }
    },

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

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

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

    _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/projects#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) {
      this._setParams({
        view: Gerrit.Nav.View.REPO,
        repo: data.params[0],
      });
    },

    _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._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._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.
      this._redirectOrNavigate({
        project: ctx.params[0],
        changeNum: ctx.params[1],
        patchNum: ctx.params[2],
        path: ctx.params[3],
        view: Gerrit.Nav.View.EDIT,
      });
    },

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

    /**
     * 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);
      }
    },

    // TODO fix this so it properly redirects
    // to /settings#Agreements (Scrolls down)
    _handleAgreementsRoute(data) {
      this._redirect('/settings/#Agreements');
    },

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

    _handleSettingsLegacyRoute(data) {
      this._setParams({
        view: Gerrit.Nav.View.SETTINGS,
        emailToken: data.params[0],
      });
    },

    _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() {
      this._show404();
    },

    _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._app.dispatchEvent(new CustomEvent('page-error',
          {detail: {response: {status: 404}}}));
    },
  });
})();
