/**
 * @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.
 */

// Navigation parameters object format:
//
// Each object has a `view` property with a value from GerritNav.View. The
// remaining properties depend on the value used for view.
//
//  - GerritNav.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.
//
// - GerritNav.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.
//
//  - GerritNav.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.
//
//  - GerritNav.View.GROUP:
//    - `groupId`, required, String: the ID of the group.
//    - `detail`, optional, String: the name of the group detail view.
//      Takes any value from GerritNav.GroupDetailView.
//
//  - GerritNav.View.REPO:
//    - `repoName`, required, String: the name of the repo
//    - `detail`, optional, String: the name of the repo detail view.
//      Takes any value from GerritNav.RepoDetailView.
//
//  - GerritNav.View.DASHBOARD
//    - `repo`, optional, String.
//    - `sections`, optional, Array of objects with `title` and `query`
//      strings.
//    - `user`, optional, String.
//
//  - GerritNav.View.ROOT:
//    - no possible parameters.

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 where the user is in the attention set.
    name: 'Your Turn',
    query: 'attention:${user}',
    hideIfEmpty: false,
    suffixForDashboard: 'limit:25',
    attentionSetOnly: true,
  },
  {
    // 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',
    assigneeOnly: true,
  },
  {
    // 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',
  },
];

// TODO(dmfilippov) Convert to class, extract consts, give better name and
// expose as a service from appContext
export const GerritNav = {

  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: GerritNav.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: GerritNav.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: GerritNav.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: GerritNav.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: GerritNav.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: GerritNav.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: GerritNav.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: GerritNav.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: GerritNav.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: GerritNav.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: GerritNav.View.SEARCH,
      owner,
    });
  },

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

  /**
   * @return {string}
   */
  getUrlForRoot() {
    return this._getUrlFor({
      view: GerritNav.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: GerritNav.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: GerritNav.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: GerritNav.View.REPO,
      repoName,
      detail: GerritNav.RepoDetailView.TAGS,
    });
  },

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

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

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

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

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

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

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

  getUrlForSettings() {
    return this._getUrlFor({view: GerritNav.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: GerritNav.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: GerritNav.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: GerritNav.WeblinkType.CHANGE, repo, commit};
    if (opt_options) {
      params.options = opt_options;
    }
    return [].concat(this._generateWeblinks(params));
  },

  getUserDashboard(user = 'self', sections = DEFAULT_SECTIONS,
      title = '', config = {}) {
    const attentionEnabled =
        config.change && !!config.change.enable_attention_set;
    const assigneeEnabled =
        config.change && !!config.change.enable_assignee;
    sections = sections
        .filter(section => (attentionEnabled || !section.attentionSetOnly))
        .filter(section => (assigneeEnabled || !section.assigneeOnly))
        .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};
  },
};
