<!--
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.
    //
    // - Gerrit.Nav.View.SEARCH:
    //    - `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.
    //
    //  - 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.

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

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

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

    const PARENT_PATCHNUM = 'PARENT';

    window.Gerrit.Nav = {

      View: {
        ADMIN: 'admin',
        CHANGE: 'change',
        AGREEMENTS: 'agreements',
        DASHBOARD: 'dashboard',
        DIFF: 'diff',
        EDIT: 'edit',
        SEARCH: 'search',
        SETTINGS: 'settings',
      },

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

      /** @type {Function} */
      _generateUrl: 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} navigate
       * @param {Function} generateUrl
       */
      setup(navigate, generateUrl) {
        this._navigate = navigate;
        this._generateUrl = generateUrl;
      },

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

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

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

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

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

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

      /**
       * @param {!Object} change The change object.
       * @param {number=} opt_patchNum
       * @param {number|string=} opt_basePatchNum The string 'PARENT' can be
       *     used for none.
       * @return {string}
       */
      getUrlForChange(change, opt_patchNum, opt_basePatchNum) {
        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,
        });
      },

      /**
       * @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.
       */
      navigateToChange(change, opt_patchNum, opt_basePatchNum) {
        this._navigate(this.getUrlForChange(change, opt_patchNum,
            opt_basePatchNum));
      },

      /**
       * @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.
       * @return {string}
       */
      getUrlForDiff(change, path, opt_patchNum, opt_basePatchNum) {
        return this.getUrlForDiffById(change._number, change.project, path,
            opt_patchNum, opt_basePatchNum);
      },

      /**
       * @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.
       * @return {string}
       */
      getEditUrlForDiff(change, path) {
        return this.getEditUrlForDiffById(change._number, change.project, path);
      },

      /**
       * @param {number} changeNum
       * @param {string} project The name of the project.
       * @param {string} path The file path.
       * @return {string}
       */
      getEditUrlForDiffById(changeNum, project, path) {
        return this._getUrlFor({
          view: Gerrit.Nav.View.EDIT,
          changeNum,
          project,
          path,
        });
      },

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

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

      getUrlForSettings() {
        return this._getUrlFor({view: Gerrit.Nav.View.SETTINGS});
      },
    };
  })(window);
</script>
