<!--
@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',
      },
      {
        // Non-WIP open changes the viewed user is CCed on. Changes ignored by the
        // viewing user are filtered out.
        name: 'CCed on',
        query: 'is:open -is:wip -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>
