<!--
@license
Copyright (C) 2017 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.
-->
<script>
  (function(window) {
    'use strict';

    // Navigation parameters object format:
    //
    // Each object has a `view` property with a value from Gerrit.Nav.View. The
    // remaining properties depend on the value used for view.
    //
    //  - Gerrit.Nav.View.CHANGE:
    //    - `changeNum`, required, String: the numeric ID of the change.
    //    - `project`, optional, String: the project name.
    //    - `patchNum`, optional, Number: the patch for the right-hand-side of
    //        the diff.
    //    - `basePatchNum`, optional, Number: the patch for the left-hand-side
    //        of the diff. If `basePatchNum` is provided, then `patchNum` must
    //        also be provided.
    //    - `edit`, optional, Boolean: whether or not to load the file list with
    //        edit controls.
    //    - `messageHash`, optional, String: the hash of the change message to
    //        scroll to.
    //
    // - Gerrit.Nav.View.SEARCH:
    //    - `query`, optional, String: the literal search query. If provided,
    //        the string will be used as the query, and all other params will be
    //        ignored.
    //    - `owner`, optional, String: the owner name.
    //    - `project`, optional, String: the project name.
    //    - `branch`, optional, String: the branch name.
    //    - `topic`, optional, String: the topic name.
    //    - `hashtag`, optional, String: the hashtag name.
    //    - `statuses`, optional, Array<String>: the list of change statuses to
    //        search for. If more than one is provided, the search will OR them
    //        together.
    //    - `offset`, optional, Number: the offset for the query.
    //
    //  - Gerrit.Nav.View.DIFF:
    //    - `changeNum`, required, String: the numeric ID of the change.
    //    - `path`, required, String: the filepath of the diff.
    //    - `patchNum`, required, Number: the patch for the right-hand-side of
    //        the diff.
    //    - `basePatchNum`, optional, Number: the patch for the left-hand-side
    //        of the diff. If `basePatchNum` is provided, then `patchNum` must
    //        also be provided.
    //    - `lineNum`, optional, Number: the line number to be selected on load.
    //    - `leftSide`, optional, Boolean: if a `lineNum` is provided, a value
    //        of true selects the line from base of the patch range. False by
    //        default.
    //
    //  - Gerrit.Nav.View.GROUP:
    //    - `groupId`, required, String: the ID of the group.
    //    - `detail`, optional, String: the name of the group detail view.
    //      Takes any value from Gerrit.Nav.GroupDetailView.
    //
    //  - Gerrit.Nav.View.REPO:
    //    - `repoName`, required, String: the name of the repo
    //    - `detail`, optional, String: the name of the repo detail view.
    //      Takes any value from Gerrit.Nav.RepoDetailView.
    //
    //  - Gerrit.Nav.View.DASHBOARD
    //    - `repo`, optional, String.
    //    - `sections`, optional, Array of objects with `title` and `query`
    //      strings.
    //    - `user`, optional, String.
    //
    //  - Gerrit.Nav.View.ROOT:
    //    - no possible parameters.

    window.Gerrit = window.Gerrit || {};

    // Prevent redefinition.
    if (window.Gerrit.hasOwnProperty('Nav')) { return; }

    const uninitialized = () => {
      console.warn('Use of uninitialized routing');
    };

    const EDIT_PATCHNUM = 'edit';
    const PARENT_PATCHNUM = 'PARENT';

    const USER_PLACEHOLDER_PATTERN = /\$\{user\}/g;

    // NOTE: These queries are tested in Java. Any changes made to definitions
    // here require corresponding changes to:
    // javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
    const DEFAULT_SECTIONS = [
      {
        // Changes with unpublished draft comments. This section is omitted when
        // viewing other users, so we don't need to filter anything out.
        name: 'Has draft comments',
        query: 'has:draft',
        selfOnly: true,
        hideIfEmpty: true,
        suffixForDashboard: 'limit:10',
      },
      {
        // Changes that are assigned to the viewed user.
        name: 'Assigned reviews',
        query: 'assignee:${user} (-is:wip OR owner:self OR assignee:self) ' +
            'is:open -is:ignored',
        hideIfEmpty: true,
        suffixForDashboard: 'limit:25',
      },
      {
        // WIP open changes owned by viewing user. This section is omitted when
        // viewing other users, so we don't need to filter anything out.
        name: 'Work in progress',
        query: 'is:open owner:${user} is:wip',
        selfOnly: true,
        hideIfEmpty: true,
        suffixForDashboard: 'limit:25',
      },
      {
        // Non-WIP open changes owned by viewed user. Filter out changes ignored
        // by the viewing user.
        name: 'Outgoing reviews',
        query: 'is:open owner:${user} -is:wip -is:ignored',
        isOutgoing: true,
        suffixForDashboard: 'limit:25',
      },
      {
        // Non-WIP open changes not owned by the viewed user, that the viewed user
        // is associated with (as either a reviewer or the assignee). Changes
        // ignored by the viewing user are filtered out.
        name: 'Incoming reviews',
        query: 'is:open -owner:${user} -is:wip -is:ignored ' +
            '(reviewer:${user} OR assignee:${user})',
        suffixForDashboard: 'limit:25',
      },
      {
        // Open changes the viewed user is CCed on. Changes ignored by the viewing
        // user are filtered out.
        name: 'CCed on',
        query: 'is:open -is:ignored cc:${user}',
        suffixForDashboard: 'limit:10',
      },
      {
        name: 'Recently closed',
        // Closed changes where viewed user is owner, reviewer, or assignee.
        // Changes ignored by the viewing user are filtered out, and so are WIP
        // changes not owned by the viewing user (the one instance of
        // 'owner:self' is intentional and implements this logic).
        query: 'is:closed -is:ignored (-is:wip OR owner:self) ' +
            '(owner:${user} OR reviewer:${user} OR assignee:${user} ' +
            'OR cc:${user})',
        suffixForDashboard: '-age:4w limit:10',
      },
    ];

    window.Gerrit.Nav = {

      View: {
        ADMIN: 'admin',
        AGREEMENTS: 'agreements',
        CHANGE: 'change',
        DASHBOARD: 'dashboard',
        DIFF: 'diff',
        DOCUMENTATION_SEARCH: 'documentation-search',
        EDIT: 'edit',
        GROUP: 'group',
        PLUGIN_SCREEN: 'plugin-screen',
        REPO: 'repo',
        ROOT: 'root',
        SEARCH: 'search',
        SETTINGS: 'settings',
      },

      GroupDetailView: {
        MEMBERS: 'members',
        LOG: 'log',
      },

      RepoDetailView: {
        ACCESS: 'access',
        BRANCHES: 'branches',
        COMMANDS: 'commands',
        DASHBOARDS: 'dashboards',
        TAGS: 'tags',
      },

      WeblinkType: {
        CHANGE: 'change',
        FILE: 'file',
        PATCHSET: 'patchset',
      },

      /** @type {Function} */
      _navigate: uninitialized,

      /** @type {Function} */
      _generateUrl: uninitialized,

      /** @type {Function} */
      _generateWeblinks: uninitialized,

      /** @type {Function} */
      mapCommentlinks: uninitialized,

      /**
       * @param {number=} patchNum
       * @param {number|string=} basePatchNum
       */
      _checkPatchRange(patchNum, basePatchNum) {
        if (basePatchNum && !patchNum) {
          throw new Error('Cannot use base patch number without patch number.');
        }
      },

      /**
       * Setup router implementation.
       * @param {function(!string)} navigate the router-abstracted equivalent of
       *     `window.location.href = ...`. Takes a string.
       * @param {function(!Object): string} generateUrl generates a URL given
       *     navigation parameters, detailed in the file header.
       * @param {function(!Object): string} generateWeblinks weblinks generator
       *     function takes single payload parameter with type property that
       *  determines which
       *     part of the UI is the consumer of the weblinks. type property can
       *     be one of file, change, or patchset.
       *     - For file type, payload will also contain string properties: repo,
       *         commit, file.
       *     - For patchset type, payload will also contain string properties:
       *         repo, commit.
       *     - For change type, payload will also contain string properties:
       *         repo, commit. If server provides weblinks, those will be passed
       *         as options.weblinks property on the main payload object.
       * @param {function(!Object): Object} mapCommentlinks provides an escape
       *     hatch to modify the commentlinks object, e.g. if it contains any
       *     relative URLs.
       */
      setup(navigate, generateUrl, generateWeblinks, mapCommentlinks) {
        this._navigate = navigate;
        this._generateUrl = generateUrl;
        this._generateWeblinks = generateWeblinks;
        this.mapCommentlinks = mapCommentlinks;
      },

      destroy() {
        this._navigate = uninitialized;
        this._generateUrl = uninitialized;
        this._generateWeblinks = uninitialized;
        this.mapCommentlinks = uninitialized;
      },

      /**
       * Generate a URL for the given route parameters.
       * @param {Object} params
       * @return {string}
       */
      _getUrlFor(params) {
        return this._generateUrl(params);
      },

      getUrlForSearchQuery(query, opt_offset) {
        return this._getUrlFor({
          view: Gerrit.Nav.View.SEARCH,
          query,
          offset: opt_offset,
        });
      },

      /**
       * @param {!string} project The name of the project.
       * @param {boolean=} opt_openOnly When true, only search open changes in
       *     the project.
       * @param {string=} opt_host The host in which to search.
       * @return {string}
       */
      getUrlForProjectChanges(project, opt_openOnly, opt_host) {
        return this._getUrlFor({
          view: Gerrit.Nav.View.SEARCH,
          project,
          statuses: opt_openOnly ? ['open'] : [],
          host: opt_host,
        });
      },

      /**
       * @param {string} branch The name of the branch.
       * @param {string} project The name of the project.
       * @param {string=} opt_status The status to search.
       * @param {string=} opt_host The host in which to search.
       * @return {string}
       */
      getUrlForBranch(branch, project, opt_status, opt_host) {
        return this._getUrlFor({
          view: Gerrit.Nav.View.SEARCH,
          branch,
          project,
          statuses: opt_status ? [opt_status] : undefined,
          host: opt_host,
        });
      },

      /**
       * @param {string} topic The name of the topic.
       * @param {string=} opt_host The host in which to search.
       * @return {string}
       */
      getUrlForTopic(topic, opt_host) {
        return this._getUrlFor({
          view: Gerrit.Nav.View.SEARCH,
          topic,
          statuses: ['open', 'merged'],
          host: opt_host,
        });
      },

      /**
       * @param {string} hashtag The name of the hashtag.
       * @return {string}
       */
      getUrlForHashtag(hashtag) {
        return this._getUrlFor({
          view: Gerrit.Nav.View.SEARCH,
          hashtag,
          statuses: ['open', 'merged'],
        });
      },

      /**
       * Navigate to a search for changes with the given status.
       * @param {string} status
       */
      navigateToStatusSearch(status) {
        this._navigate(this._getUrlFor({
          view: Gerrit.Nav.View.SEARCH,
          statuses: [status],
        }));
      },

      /**
       * Navigate to a search query
       * @param {string} query
       * @param {number=} opt_offset
       */
      navigateToSearchQuery(query, opt_offset) {
        return this._navigate(this.getUrlForSearchQuery(query, opt_offset));
      },

      /**
       * Navigate to the user's dashboard
       */
      navigateToUserDashboard() {
        return this._navigate(this.getUrlForUserDashboard('self'));
      },

      /**
       * @param {!Object} change The change object.
       * @param {number=} opt_patchNum
       * @param {number|string=} opt_basePatchNum The string 'PARENT' can be
       *     used for none.
       * @param {boolean=} opt_isEdit
       * @param {string=} opt_messageHash
       * @return {string}
       */
      getUrlForChange(change, opt_patchNum, opt_basePatchNum, opt_isEdit,
          opt_messageHash) {
        if (opt_basePatchNum === PARENT_PATCHNUM) {
          opt_basePatchNum = undefined;
        }

        this._checkPatchRange(opt_patchNum, opt_basePatchNum);
        return this._getUrlFor({
          view: Gerrit.Nav.View.CHANGE,
          changeNum: change._number,
          project: change.project,
          patchNum: opt_patchNum,
          basePatchNum: opt_basePatchNum,
          edit: opt_isEdit,
          host: change.internalHost || undefined,
          messageHash: opt_messageHash,
        });
      },

      /**
       * @param {number} changeNum
       * @param {string} project The name of the project.
       * @param {number=} opt_patchNum
       * @return {string}
       */
      getUrlForChangeById(changeNum, project, opt_patchNum) {
        return this._getUrlFor({
          view: Gerrit.Nav.View.CHANGE,
          changeNum,
          project,
          patchNum: opt_patchNum,
        });
      },

      /**
       * @param {!Object} change The change object.
       * @param {number=} opt_patchNum
       * @param {number|string=} opt_basePatchNum The string 'PARENT' can be
       *     used for none.
       * @param {boolean=} opt_isEdit
       */
      navigateToChange(change, opt_patchNum, opt_basePatchNum, opt_isEdit) {
        this._navigate(this.getUrlForChange(change, opt_patchNum,
            opt_basePatchNum, opt_isEdit));
      },

      /**
       * @param {{ _number: number, project: string }} change The change object.
       * @param {string} path The file path.
       * @param {number=} opt_patchNum
       * @param {number|string=} opt_basePatchNum The string 'PARENT' can be
       *     used for none.
       * @param {number|string=} opt_lineNum
       * @return {string}
       */
      getUrlForDiff(change, path, opt_patchNum, opt_basePatchNum, opt_lineNum) {
        return this.getUrlForDiffById(change._number, change.project, path,
            opt_patchNum, opt_basePatchNum, opt_lineNum);
      },

      /**
       * @param {number} changeNum
       * @param {string} project The name of the project.
       * @param {string} path The file path.
       * @param {number=} opt_patchNum
       * @param {number|string=} opt_basePatchNum The string 'PARENT' can be
       *     used for none.
       * @param {number=} opt_lineNum
       * @param {boolean=} opt_leftSide
       * @return {string}
       */
      getUrlForDiffById(changeNum, project, path, opt_patchNum,
          opt_basePatchNum, opt_lineNum, opt_leftSide) {
        if (opt_basePatchNum === PARENT_PATCHNUM) {
          opt_basePatchNum = undefined;
        }

        this._checkPatchRange(opt_patchNum, opt_basePatchNum);
        return this._getUrlFor({
          view: Gerrit.Nav.View.DIFF,
          changeNum,
          project,
          path,
          patchNum: opt_patchNum,
          basePatchNum: opt_basePatchNum,
          lineNum: opt_lineNum,
          leftSide: opt_leftSide,
        });
      },

      /**
       * @param {{ _number: number, project: string }} change The change object.
       * @param {string} path The file path.
       * @param {number=} opt_patchNum
       * @return {string}
       */
      getEditUrlForDiff(change, path, opt_patchNum) {
        return this.getEditUrlForDiffById(change._number, change.project, path,
            opt_patchNum);
      },

      /**
       * @param {number} changeNum
       * @param {string} project The name of the project.
       * @param {string} path The file path.
       * @param {number|string=} opt_patchNum The patchNum the file content
       *    should be based on, or ${EDIT_PATCHNUM} if left undefined.
       * @return {string}
       */
      getEditUrlForDiffById(changeNum, project, path, opt_patchNum) {
        return this._getUrlFor({
          view: Gerrit.Nav.View.EDIT,
          changeNum,
          project,
          path,
          patchNum: opt_patchNum || EDIT_PATCHNUM,
        });
      },

      /**
       * @param {!Object} change The change object.
       * @param {string} path The file path.
       * @param {number=} opt_patchNum
       * @param {number|string=} opt_basePatchNum The string 'PARENT' can be
       *     used for none.
       */
      navigateToDiff(change, path, opt_patchNum, opt_basePatchNum) {
        this._navigate(this.getUrlForDiff(change, path, opt_patchNum,
            opt_basePatchNum));
      },

      /**
       * @param {string} owner The name of the owner.
       * @return {string}
       */
      getUrlForOwner(owner) {
        return this._getUrlFor({
          view: Gerrit.Nav.View.SEARCH,
          owner,
        });
      },

      /**
       * @param {string} user The name of the user.
       * @return {string}
       */
      getUrlForUserDashboard(user) {
        return this._getUrlFor({
          view: Gerrit.Nav.View.DASHBOARD,
          user,
        });
      },

      /**
       * @return {string}
       */
      getUrlForRoot() {
        return this._getUrlFor({
          view: Gerrit.Nav.View.ROOT,
        });
      },

      /**
       * @param {string} repo The name of the repo.
       * @param {string} dashboard The ID of the dashboard, in the form of
       *     '<ref>:<path>'.
       * @return {string}
       */
      getUrlForRepoDashboard(repo, dashboard) {
        return this._getUrlFor({
          view: Gerrit.Nav.View.DASHBOARD,
          repo,
          dashboard,
        });
      },

      /**
       * Navigate to an arbitrary relative URL.
       * @param {string} relativeUrl
       */
      navigateToRelativeUrl(relativeUrl) {
        if (!relativeUrl.startsWith('/')) {
          throw new Error('navigateToRelativeUrl with non-relative URL');
        }
        this._navigate(relativeUrl);
      },

      /**
       * @param {string} repoName
       * @return {string}
       */
      getUrlForRepo(repoName) {
        return this._getUrlFor({
          view: Gerrit.Nav.View.REPO,
          repoName,
        });
      },

      /**
       * Navigate to a repo settings page.
       * @param {string} repoName
       */
      navigateToRepo(repoName) {
        this._navigate(this.getUrlForRepo(repoName));
      },

      /**
       * @param {string} repoName
       * @return {string}
       */
      getUrlForRepoTags(repoName) {
        return this._getUrlFor({
          view: Gerrit.Nav.View.REPO,
          repoName,
          detail: Gerrit.Nav.RepoDetailView.TAGS,
        });
      },

      /**
       * @param {string} repoName
       * @return {string}
       */
      getUrlForRepoBranches(repoName) {
        return this._getUrlFor({
          view: Gerrit.Nav.View.REPO,
          repoName,
          detail: Gerrit.Nav.RepoDetailView.BRANCHES,
        });
      },

      /**
       * @param {string} repoName
       * @return {string}
       */
      getUrlForRepoAccess(repoName) {
        return this._getUrlFor({
          view: Gerrit.Nav.View.REPO,
          repoName,
          detail: Gerrit.Nav.RepoDetailView.ACCESS,
        });
      },

      /**
       * @param {string} repoName
       * @return {string}
       */
      getUrlForRepoCommands(repoName) {
        return this._getUrlFor({
          view: Gerrit.Nav.View.REPO,
          repoName,
          detail: Gerrit.Nav.RepoDetailView.COMMANDS,
        });
      },

      /**
       * @param {string} repoName
       * @return {string}
       */
      getUrlForRepoDashboards(repoName) {
        return this._getUrlFor({
          view: Gerrit.Nav.View.REPO,
          repoName,
          detail: Gerrit.Nav.RepoDetailView.DASHBOARDS,
        });
      },

      /**
       * @param {string} groupId
       * @return {string}
       */
      getUrlForGroup(groupId) {
        return this._getUrlFor({
          view: Gerrit.Nav.View.GROUP,
          groupId,
        });
      },

      /**
       * @param {string} groupId
       * @return {string}
       */
      getUrlForGroupLog(groupId) {
        return this._getUrlFor({
          view: Gerrit.Nav.View.GROUP,
          groupId,
          detail: Gerrit.Nav.GroupDetailView.LOG,
        });
      },

      /**
       * @param {string} groupId
       * @return {string}
       */
      getUrlForGroupMembers(groupId) {
        return this._getUrlFor({
          view: Gerrit.Nav.View.GROUP,
          groupId,
          detail: Gerrit.Nav.GroupDetailView.MEMBERS,
        });
      },

      getUrlForSettings() {
        return this._getUrlFor({view: Gerrit.Nav.View.SETTINGS});
      },

      /**
       * @param {string} repo
       * @param {string} commit
       * @param {string} file
       * @param {Object=} opt_options
       * @return {
       *   Array<{label: string, url: string}>|
       *   {label: string, url: string}
       *  }
       */
      getFileWebLinks(repo, commit, file, opt_options) {
        const params = {type: Gerrit.Nav.WeblinkType.FILE, repo, commit, file};
        if (opt_options) {
          params.options = opt_options;
        }
        return [].concat(this._generateWeblinks(params));
      },

      /**
       * @param {string} repo
       * @param {string} commit
       * @param {Object=} opt_options
       * @return {{label: string, url: string}}
       */
      getPatchSetWeblink(repo, commit, opt_options) {
        const params = {type: Gerrit.Nav.WeblinkType.PATCHSET, repo, commit};
        if (opt_options) {
          params.options = opt_options;
        }
        const result = this._generateWeblinks(params);
        if (Array.isArray(result)) {
          return result.pop();
        } else {
          return result;
        }
      },

      /**
       * @param {string} repo
       * @param {string} commit
       * @param {Object=} opt_options
       * @return {
       *   Array<{label: string, url: string}>|
       *   {label: string, url: string}
       *  }
       */
      getChangeWeblinks(repo, commit, opt_options) {
        const params = {type: Gerrit.Nav.WeblinkType.CHANGE, repo, commit};
        if (opt_options) {
          params.options = opt_options;
        }
        return [].concat(this._generateWeblinks(params));
      },

      getUserDashboard(user = 'self', sections = DEFAULT_SECTIONS,
          title = '') {
        sections = sections
          .filter(section => (user === 'self' || !section.selfOnly))
          .map(section => Object.assign({}, section, {
            name: section.name,
            query: section.query.replace(USER_PLACEHOLDER_PATTERN, user),
          }));
        return {title, sections};
      },
    };
  })(window);
</script>
