<!--
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.
    //    - `hashtags`, optional, Array<String>: the list of hashtags names.
    //    - `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',
        SEARCH: 'search',
        SETTINGS: 'settings',
      },

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

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

      /**
       * Handler for when a legacy URL can be upgraded. Router implementations
       * may implement as a no-op if route upgrades are not needed.
       *
       * @type {Function}
       */
      _upgradeUrl: 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
       * @param {Function} upgradeUrl
       */
      setup(navigate, generateUrl, upgradeUrl) {
        this._navigate = navigate;
        this._generateUrl = generateUrl;
        this._upgradeUrl = upgradeUrl;
      },

      destroy() {
        this._navigate = uninitialized;
        this._generateUrl = uninitialized;
        this._upgradeUrl = 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 {!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 {!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,
        });
      },

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

      upgradeUrl(params) {
        this._upgradeUrl(params);
      },
    };
  })(window);
</script>
