// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * @fileoverview Issue actions, selectors, and reducers organized into
 * a single Redux "Duck" that manages updating and retrieving issue state
 * on the frontend.
 *
 * Reference: https://github.com/erikras/ducks-modular-redux
 */

import {combineReducers} from 'redux';
import {createSelector} from 'reselect';
import {autolink} from 'autolink.js';
import {fieldTypes, extractTypeForIssue,
  fieldValuesToMap} from 'shared/issue-fields.js';
import {removePrefix, objectToMap} from 'shared/helpers.js';
import {issueRefToString, issueToIssueRefString,
  issueStringToRef, issueNameToRefString} from 'shared/convertersV0.js';
import {fromShortlink} from 'shared/federated.js';
import {createReducer, createRequestReducer,
  createKeyedRequestReducer} from './redux-helpers.js';
import * as projectV0 from './projectV0.js';
import * as userV0 from './userV0.js';
import {fieldValueMapKey} from 'shared/metadata-helpers.js';
import {prpcClient} from 'prpc-client-instance.js';
import loadGapi, {fetchGapiEmail} from 'shared/gapi-loader.js';
import 'shared/typedef.js';

/** @typedef {import('redux').AnyAction} AnyAction */

// Actions
export const VIEW_ISSUE = 'VIEW_ISSUE';

export const FETCH_START = 'issueV0/FETCH_START';
export const FETCH_SUCCESS = 'issueV0/FETCH_SUCCESS';
export const FETCH_FAILURE = 'issueV0/FETCH_FAILURE';

export const FETCH_ISSUES_START = 'issueV0/FETCH_ISSUES_START';
export const FETCH_ISSUES_SUCCESS = 'issueV0/FETCH_ISSUES_SUCCESS';
export const FETCH_ISSUES_FAILURE = 'issueV0/FETCH_ISSUES_FAILURE';

const FETCH_HOTLISTS_START = 'FETCH_HOTLISTS_START';
export const FETCH_HOTLISTS_SUCCESS = 'FETCH_HOTLISTS_SUCCESS';
const FETCH_HOTLISTS_FAILURE = 'FETCH_HOTLISTS_FAILURE';

const FETCH_ISSUE_LIST_START = 'FETCH_ISSUE_LIST_START';
export const FETCH_ISSUE_LIST_UPDATE = 'FETCH_ISSUE_LIST_UPDATE';
const FETCH_ISSUE_LIST_SUCCESS = 'FETCH_ISSUE_LIST_SUCCESS';
const FETCH_ISSUE_LIST_FAILURE = 'FETCH_ISSUE_LIST_FAILURE';

const FETCH_PERMISSIONS_START = 'FETCH_PERMISSIONS_START';
const FETCH_PERMISSIONS_SUCCESS = 'FETCH_PERMISSIONS_SUCCESS';
const FETCH_PERMISSIONS_FAILURE = 'FETCH_PERMISSIONS_FAILURE';

export const STAR_START = 'STAR_START';
export const STAR_SUCCESS = 'STAR_SUCCESS';
const STAR_FAILURE = 'STAR_FAILURE';

const PRESUBMIT_START = 'PRESUBMIT_START';
const PRESUBMIT_SUCCESS = 'PRESUBMIT_SUCCESS';
const PRESUBMIT_FAILURE = 'PRESUBMIT_FAILURE';

export const FETCH_IS_STARRED_START = 'FETCH_IS_STARRED_START';
export const FETCH_IS_STARRED_SUCCESS = 'FETCH_IS_STARRED_SUCCESS';
const FETCH_IS_STARRED_FAILURE = 'FETCH_IS_STARRED_FAILURE';

const FETCH_ISSUES_STARRED_START = 'FETCH_ISSUES_STARRED_START';
export const FETCH_ISSUES_STARRED_SUCCESS = 'FETCH_ISSUES_STARRED_SUCCESS';
const FETCH_ISSUES_STARRED_FAILURE = 'FETCH_ISSUES_STARRED_FAILURE';

const FETCH_COMMENTS_START = 'FETCH_COMMENTS_START';
export const FETCH_COMMENTS_SUCCESS = 'FETCH_COMMENTS_SUCCESS';
const FETCH_COMMENTS_FAILURE = 'FETCH_COMMENTS_FAILURE';

const FETCH_COMMENT_REFERENCES_START = 'FETCH_COMMENT_REFERENCES_START';
const FETCH_COMMENT_REFERENCES_SUCCESS = 'FETCH_COMMENT_REFERENCES_SUCCESS';
const FETCH_COMMENT_REFERENCES_FAILURE = 'FETCH_COMMENT_REFERENCES_FAILURE';

const FETCH_REFERENCED_USERS_START = 'FETCH_REFERENCED_USERS_START';
const FETCH_REFERENCED_USERS_SUCCESS = 'FETCH_REFERENCED_USERS_SUCCESS';
const FETCH_REFERENCED_USERS_FAILURE = 'FETCH_REFERENCED_USERS_FAILURE';

const FETCH_RELATED_ISSUES_START = 'FETCH_RELATED_ISSUES_START';
const FETCH_RELATED_ISSUES_SUCCESS = 'FETCH_RELATED_ISSUES_SUCCESS';
const FETCH_RELATED_ISSUES_FAILURE = 'FETCH_RELATED_ISSUES_FAILURE';

const FETCH_FEDERATED_REFERENCES_START = 'FETCH_FEDERATED_REFERENCES_START';
const FETCH_FEDERATED_REFERENCES_SUCCESS = 'FETCH_FEDERATED_REFERENCES_SUCCESS';
const FETCH_FEDERATED_REFERENCES_FAILURE = 'FETCH_FEDERATED_REFERENCES_FAILURE';

const CONVERT_START = 'CONVERT_START';
const CONVERT_SUCCESS = 'CONVERT_SUCCESS';
const CONVERT_FAILURE = 'CONVERT_FAILURE';

const UPDATE_START = 'UPDATE_START';
const UPDATE_SUCCESS = 'UPDATE_SUCCESS';
const UPDATE_FAILURE = 'UPDATE_FAILURE';

const UPDATE_APPROVAL_START = 'UPDATE_APPROVAL_START';
const UPDATE_APPROVAL_SUCCESS = 'UPDATE_APPROVAL_SUCCESS';
const UPDATE_APPROVAL_FAILURE = 'UPDATE_APPROVAL_FAILURE';

/* State Shape
{
  issuesByRefString: Object<IssueRefString, Issue>,

  viewedIssueRef: IssueRefString,

  hotlists: Array<HotlistV0>,
  issueList: {
    issueRefs: Array<IssueRefString>,
    progress: number,
    totalResults: number,
  }
  comments: Array<IssueComment>,
  commentReferences: Object,
  relatedIssues: Object,
  referencedUsers: Array<UserV0>,
  starredIssues: Object<IssueRefString, Boolean>,
  permissions: Array<string>,
  presubmitResponse: Object,

  requests: {
    fetch: ReduxRequestState,
    fetchHotlists: ReduxRequestState,
    fetchIssueList: ReduxRequestState,
    fetchPermissions: ReduxRequestState,
    starringIssues: Object<string, ReduxRequestState>,
    presubmit: ReduxRequestState,
    fetchComments: ReduxRequestState,
    fetchCommentReferences: ReduxRequestState,
    fetchFederatedReferences: ReduxRequestState,
    fetchRelatedIssues: ReduxRequestState,
    fetchStarredIssues: ReduxRequestState,
    fetchStarredIssues: ReduxRequestState,
    convert: ReduxRequestState,
    update: ReduxRequestState,
    updateApproval: ReduxRequestState,
  },
}
*/

// Helpers for the reducers.

/**
 * Overrides local data for single approval on an Issue object with fresh data.
 * Note that while an Issue can have multiple approvals, this function only
 * refreshes data for a single approval.
 * @param {Issue} issue Issue Object being updated.
 * @param {ApprovalDef} approval A single approval to override in the issue.
 * @return {Issue} Issue with updated approval data.
 */
const updateApprovalValues = (issue, approval) => {
  if (!issue.approvalValues) return issue;
  const newApprovals = issue.approvalValues.map((item) => {
    if (item.fieldRef.fieldName === approval.fieldRef.fieldName) {
      // PhaseRef isn't populated on the response so we want to make sure
      // it doesn't overwrite the original phaseRef with {}.
      return {...approval, phaseRef: item.phaseRef};
    }
    return item;
  });
  return {...issue, approvalValues: newApprovals};
};

// Reducers

/**
 * Creates a new issuesByRefString Object with a single issue's data
 * edited.
 * @param {Object<IssueRefString, Issue>} issuesByRefString
 * @param {Issue} issue The new issue data to add to the state.
 * @return {Object<IssueRefString, Issue>}
 */
const updateSingleIssueInState = (issuesByRefString, issue) => {
  return {
    ...issuesByRefString,
    [issueToIssueRefString(issue)]: issue,
  };
};

// TODO(crbug.com/monorail/6882): Finish converting all other issue
//   actions to use this format.
/**
 * Adds issues fetched by a ListIssues request to the Redux store in a
 * normalized format.
 * @param {Object<IssueRefString, Issue>} state Redux state.
 * @param {AnyAction} action
 * @param {Array<Issue>} action.issues The list of issues that was fetched.
 * @param {Issue=} action.issue The issue being updated.
 * @param {number=} action.starCount Number of stars the issue has. This changes
 *   when a user stars an issue and needs to be updated.
 * @param {ApprovalDef=} action.approval A new approval to update the issue
 *   with.
 * @param {IssueRef=} action.issueRef A specific IssueRef to update.
 */
export const issuesByRefStringReducer = createReducer({}, {
  [FETCH_ISSUE_LIST_UPDATE]: (state, {issues}) => {
    const newState = {...state};

    issues.forEach((issue) => {
      const refString = issueToIssueRefString(issue);
      newState[refString] = {...newState[refString], ...issue};
    });

    return newState;
  },
  [FETCH_SUCCESS]: (state, {issue}) => updateSingleIssueInState(state, issue),
  [FETCH_ISSUES_SUCCESS]: (state, {issues}) => {
    const newState = {...state};

    issues.forEach((issue) => {
      const refString = issueToIssueRefString(issue);
      newState[refString] = {...newState[refString], ...issue};
    });

    return newState;
  },
  [CONVERT_SUCCESS]: (state, {issue}) => updateSingleIssueInState(state, issue),
  [UPDATE_SUCCESS]: (state, {issue}) => updateSingleIssueInState(state, issue),
  [UPDATE_APPROVAL_SUCCESS]: (state, {issueRef, approval}) => {
    const issueRefString = issueToIssueRefString(issueRef);
    const originalIssue = state[issueRefString] || {};
    const newIssue = updateApprovalValues(originalIssue, approval);
    return {
      ...state,
      [issueRefString]: {
        ...newIssue,
      },
    };
  },
  [STAR_SUCCESS]: (state, {issueRef, starCount}) => {
    const issueRefString = issueToIssueRefString(issueRef);
    const originalIssue = state[issueRefString] || {};
    return {
      ...state,
      [issueRefString]: {
        ...originalIssue,
        starCount,
      },
    };
  },
});

/**
 * Sets a reference for the issue that the user is currently viewing.
 * @param {IssueRefString} state Currently viewed issue.
 * @param {AnyAction} action
 * @param {IssueRef} action.issueRef The updated localId to view.
 * @return {IssueRefString}
 */
const viewedIssueRefReducer = createReducer('', {
  [VIEW_ISSUE]: (state, {issueRef}) => issueRefToString(issueRef) || state,
});

/**
 * Reducer to manage updating the list of hotlists attached to an Issue.
 * @param {Array<HotlistV0>} state List of issue hotlists.
 * @param {AnyAction} action
 * @param {Array<HotlistV0>} action.hotlists New list of hotlists.
 * @return {Array<HotlistV0>}
 */
const hotlistsReducer = createReducer([], {
  [FETCH_HOTLISTS_SUCCESS]: (_, {hotlists}) => hotlists,
});

/**
 * @typedef {Object} IssueListState
 * @property {Array<IssueRefString>} issues The list of issues being viewed,
 *   in a normalized form.
 * @property {number} progress The percentage of issues loaded. Used for
 *   incremental loading of issues in the grid view.
 * @property {number} totalResults The total number of issues matching the
 *   query.
 */

/**
 * Handles the state of the currently viewed issue list. This reducer
 * stores this data in normalized form.
 * @param {IssueListState} state
 * @param {AnyAction} action
 * @param {Array<Issue>} action.issues Issues that were fetched.
 * @param {number} state.progress New percentage of issues have been loaded.
 * @param {number} state.totalResults The total number of issues matching the
 *   query.
 * @return {IssueListState}
 */
export const issueListReducer = createReducer({}, {
  [FETCH_ISSUE_LIST_UPDATE]: (_state, {issues, progress, totalResults}) => ({
    issueRefs: issues.map(issueToIssueRefString), progress, totalResults,
  }),
});

/**
 * Updates the comments attached to the currently viewed issue.
 * @param {Array<IssueComment>} state The list of comments in an issue.
 * @param {AnyAction} action
 * @param {Array<IssueComment>} action.comments Fetched comments.
 * @return {Array<IssueComment>}
 */
const commentsReducer = createReducer([], {
  [FETCH_COMMENTS_SUCCESS]: (_state, {comments}) => comments,
});

// TODO(crbug.com/monorail/5953): Come up with some way to refactor
// autolink.js's reference code to allow avoiding duplicate lookups
// with data already in Redux state.
/**
 * For autolinking, this reducer stores the dereferenced data for bits
 * of data that were referenced in comments. For example, comments might
 * include user emails or IDs for other issues, and this state slice would
 * store the full Objects for that data.
 * @param {Array<CommentReference>} state
 * @param {AnyAction} action
 * @param {Array<CommentReference>} action.commentReferences New references
 *   to store.
 * @return {Array<CommentReference>}
 */
const commentReferencesReducer = createReducer({}, {
  [FETCH_COMMENTS_START]: (_state, _action) => ({}),
  [FETCH_COMMENT_REFERENCES_SUCCESS]: (_state, {commentReferences}) => {
    return commentReferences;
  },
});

/**
 * Handles state for related issues such as blocking and blocked on issues,
 * including federated references that could reference external issues outside
 * Monorail.
 * @param {Object<IssueRefString, Issue>} state
 * @param {AnyAction} action
 * @param {Object<IssueRefString, Issue>=} action.relatedIssues New related
 *   issues.
 * @param {Array<IssueRef>=} action.fedRefIssueRefs List of fetched federated
 *   issue references.
 * @return {Object<IssueRefString, Issue>}
 */
export const relatedIssuesReducer = createReducer({}, {
  [FETCH_RELATED_ISSUES_SUCCESS]: (_state, {relatedIssues}) => relatedIssues,
  [FETCH_FEDERATED_REFERENCES_SUCCESS]: (state, {fedRefIssueRefs}) => {
    if (!fedRefIssueRefs) {
      return state;
    }

    const fedRefStates = {};
    fedRefIssueRefs.forEach((ref) => {
      fedRefStates[ref.extIdentifier] = ref;
    });

    // Return a new object, in Redux fashion.
    return Object.assign(fedRefStates, state);
  },
});

/**
 * Stores data for users referenced by issue. ie: Owner, CC, etc.
 * @param {Object<string, UserV0>} state
 * @param {AnyAction} action
 * @param {Object<string, UserV0>} action.referencedUsers
 * @return {Object<string, UserV0>}
 */
const referencedUsersReducer = createReducer({}, {
  [FETCH_REFERENCED_USERS_SUCCESS]: (_state, {referencedUsers}) =>
    referencedUsers,
});

/**
 * Handles updating state of all starred issues.
 * @param {Object<IssueRefString, boolean>} state Set of starred issues,
 *   stored in a serializeable Object form.
 * @param {AnyAction} action
 * @param {IssueRef=} action.issueRef An issue with a star state being updated.
 * @param {boolean=} action.starred Whether the issue is starred or unstarred.
 * @param {Array<IssueRef>=} action.starredIssueRefs A list of starred issues.
 * @return {Object<IssueRefString, boolean>}
 */
export const starredIssuesReducer = createReducer({}, {
  [STAR_SUCCESS]: (state, {issueRef, starred}) => {
    return {...state, [issueRefToString(issueRef)]: starred};
  },
  [FETCH_ISSUES_STARRED_SUCCESS]: (_state, {starredIssueRefs}) => {
    const normalizedStars = {};
    starredIssueRefs.forEach((issueRef) => {
      normalizedStars[issueRefToString(issueRef)] = true;
    });
    return normalizedStars;
  },
  [FETCH_IS_STARRED_SUCCESS]: (state, {issueRef, starred}) => {
    const refString = issueRefToString(issueRef);
    return {...state, [refString]: starred};
  },
});

/**
 * Adds the result of an IssuePresubmit response to the Redux store.
 * @param {Object} state Initial Redux state.
 * @param {AnyAction} action
 * @param {Object} action.presubmitResponse The issue
 *   presubmit response Object.
 * @return {Object}
 */
const presubmitResponseReducer = createReducer({}, {
  [PRESUBMIT_SUCCESS]: (_state, {presubmitResponse}) => presubmitResponse,
});

/**
 * Stores the user's permissions for a given issue.
 * @param {Array<string>} state Permission list. Each permission is a string
 *   with the name of the permission.
 * @param {AnyAction} action
 * @param {Array<string>} action.permissions The fetched permission data.
 * @return {Array<string>}
 */
const permissionsReducer = createReducer([], {
  [FETCH_PERMISSIONS_SUCCESS]: (_state, {permissions}) => permissions,
});

const requestsReducer = combineReducers({
  fetch: createRequestReducer(
      FETCH_START, FETCH_SUCCESS, FETCH_FAILURE),
  fetchIssues: createRequestReducer(
      FETCH_ISSUES_START, FETCH_ISSUES_SUCCESS, FETCH_ISSUES_FAILURE),
  fetchHotlists: createRequestReducer(
      FETCH_HOTLISTS_START, FETCH_HOTLISTS_SUCCESS, FETCH_HOTLISTS_FAILURE),
  fetchIssueList: createRequestReducer(
      FETCH_ISSUE_LIST_START,
      FETCH_ISSUE_LIST_SUCCESS,
      FETCH_ISSUE_LIST_FAILURE),
  fetchPermissions: createRequestReducer(
      FETCH_PERMISSIONS_START,
      FETCH_PERMISSIONS_SUCCESS,
      FETCH_PERMISSIONS_FAILURE),
  starringIssues: createKeyedRequestReducer(
      STAR_START, STAR_SUCCESS, STAR_FAILURE),
  presubmit: createRequestReducer(
      PRESUBMIT_START, PRESUBMIT_SUCCESS, PRESUBMIT_FAILURE),
  fetchComments: createRequestReducer(
      FETCH_COMMENTS_START, FETCH_COMMENTS_SUCCESS, FETCH_COMMENTS_FAILURE),
  fetchCommentReferences: createRequestReducer(
      FETCH_COMMENT_REFERENCES_START,
      FETCH_COMMENT_REFERENCES_SUCCESS,
      FETCH_COMMENT_REFERENCES_FAILURE),
  fetchFederatedReferences: createRequestReducer(
      FETCH_FEDERATED_REFERENCES_START,
      FETCH_FEDERATED_REFERENCES_SUCCESS,
      FETCH_FEDERATED_REFERENCES_FAILURE),
  fetchRelatedIssues: createRequestReducer(
      FETCH_RELATED_ISSUES_START,
      FETCH_RELATED_ISSUES_SUCCESS,
      FETCH_RELATED_ISSUES_FAILURE),
  fetchReferencedUsers: createRequestReducer(
      FETCH_REFERENCED_USERS_START,
      FETCH_REFERENCED_USERS_SUCCESS,
      FETCH_REFERENCED_USERS_FAILURE),
  fetchIsStarred: createRequestReducer(
      FETCH_IS_STARRED_START, FETCH_IS_STARRED_SUCCESS,
      FETCH_IS_STARRED_FAILURE),
  fetchStarredIssues: createRequestReducer(
      FETCH_ISSUES_STARRED_START, FETCH_ISSUES_STARRED_SUCCESS,
      FETCH_ISSUES_STARRED_FAILURE,
  ),
  convert: createRequestReducer(
      CONVERT_START, CONVERT_SUCCESS, CONVERT_FAILURE),
  update: createRequestReducer(
      UPDATE_START, UPDATE_SUCCESS, UPDATE_FAILURE),
  // TODO(zhangtiff): Update this to use createKeyedRequestReducer() instead, so
  // users can update multiple approvals at once.
  updateApproval: createRequestReducer(
      UPDATE_APPROVAL_START, UPDATE_APPROVAL_SUCCESS, UPDATE_APPROVAL_FAILURE),
});

export const reducer = combineReducers({
  viewedIssueRef: viewedIssueRefReducer,

  issuesByRefString: issuesByRefStringReducer,

  hotlists: hotlistsReducer,
  issueList: issueListReducer,
  comments: commentsReducer,
  commentReferences: commentReferencesReducer,
  relatedIssues: relatedIssuesReducer,
  referencedUsers: referencedUsersReducer,
  starredIssues: starredIssuesReducer,
  permissions: permissionsReducer,
  presubmitResponse: presubmitResponseReducer,

  requests: requestsReducer,
});

// Selectors
const RESTRICT_VIEW_PREFIX = 'restrict-view-';
const RESTRICT_EDIT_PREFIX = 'restrict-editissue-';
const RESTRICT_COMMENT_PREFIX = 'restrict-addissuecomment-';

/**
 * Selector to retrieve all normalized Issue data in the Redux store,
 * keyed by IssueRefString.
 * @param {any} state
 * @return {Object<IssueRefString, Issue>}
 */
const issuesByRefString = (state) => state.issue.issuesByRefString;

/**
 * Selector to return a function to retrieve an Issue from the Redux store.
 * @param {any} state
 * @return {function(string): ?Issue}
 */
export const issue = createSelector(issuesByRefString, (issuesByRefString) =>
  (name) => issuesByRefString[issueNameToRefString(name)]);

/**
 * Selector to return a function to retrieve a given Issue Object from
 * the Redux store.
 * @param {any} state
 * @return {function(IssueRefString, string): Issue}
 */
export const issueForRefString = createSelector(issuesByRefString,
    (issuesByRefString) => (issueRefString, projectName = undefined) => {
      // In some contexts, an issue ref string will omit a project name,
      // assuming the default project to be the project name. We never
      // omit the project name in strings used as keys, so we have to
      // make sure issue ref strings contain the project name.
      const ref = issueStringToRef(issueRefString, projectName);
      const refString = issueRefToString(ref);
      if (issuesByRefString.hasOwnProperty(refString)) {
        return issuesByRefString[refString];
      }
      return issueStringToRef(refString, projectName);
    });

/**
 * Selector to get a reference to the currently viewed issue, in string form.
 * @param {any} state
 * @return {IssueRefString}
 */
const viewedIssueRefString = (state) => state.issue.viewedIssueRef;

/**
 * Selector to get a reference to the currently viewed issue.
 * @param {any} state
 * @return {IssueRef}
 */
export const viewedIssueRef = createSelector(viewedIssueRefString,
    (viewedIssueRefString) => issueStringToRef(viewedIssueRefString));

/**
 * Selector to get the full Issue data for the currently viewed issue.
 * @param {any} state
 * @return {Issue}
 */
export const viewedIssue = createSelector(issuesByRefString,
    viewedIssueRefString,
    (issuesByRefString, viewedIssueRefString) =>
      issuesByRefString[viewedIssueRefString] || {});

export const comments = (state) => state.issue.comments;
export const commentsLoaded = (state) => state.issue.commentsLoaded;

const _commentReferences = (state) => state.issue.commentReferences;
export const commentReferences = createSelector(_commentReferences,
    (commentReferences) => objectToMap(commentReferences));

export const hotlists = (state) => state.issue.hotlists;

const stateIssueList = (state) => state.issue.issueList;
export const issueList = createSelector(
    issuesByRefString,
    stateIssueList,
    (issuesByRefString, stateIssueList) => {
      return (stateIssueList.issueRefs || []).map((issueRef) => {
        return issuesByRefString[issueRef];
      });
    },
);
export const totalIssues = (state) => state.issue.issueList.totalResults;
export const issueListProgress = (state) => state.issue.issueList.progress;
export const issueListPhaseNames = createSelector(issueList, (issueList) => {
  const phaseNamesSet = new Set();
  if (issueList) {
    issueList.forEach(({phases}) => {
      if (phases) {
        phases.forEach(({phaseRef: {phaseName}}) => {
          phaseNamesSet.add(phaseName.toLowerCase());
        });
      }
    });
  }
  return Array.from(phaseNamesSet);
});

/**
 * @param {any} state
 * @return {boolean} Whether the currently viewed issue list
 *   has loaded.
 */
export const issueListLoaded = createSelector(
    stateIssueList,
    (stateIssueList) => stateIssueList.issueRefs !== undefined);

export const permissions = (state) => state.issue.permissions;
export const presubmitResponse = (state) => state.issue.presubmitResponse;

const _relatedIssues = (state) => state.issue.relatedIssues || {};
export const relatedIssues = createSelector(_relatedIssues,
    (relatedIssues) => objectToMap(relatedIssues));

const _referencedUsers = (state) => state.issue.referencedUsers || {};
export const referencedUsers = createSelector(_referencedUsers,
    (referencedUsers) => objectToMap(referencedUsers));

export const isStarred = (state) => state.issue.isStarred;
export const _starredIssues = (state) => state.issue.starredIssues;

export const requests = (state) => state.issue.requests;

// Returns a Map of in flight StarIssues requests, keyed by issueRef.
export const starringIssues = createSelector(requests, (requests) =>
  objectToMap(requests.starringIssues));

export const starredIssues = createSelector(
    _starredIssues,
    (starredIssues) => {
      const stars = new Set();
      for (const [ref, starred] of Object.entries(starredIssues)) {
        if (starred) stars.add(ref);
      }
      return stars;
    },
);

// TODO(zhangtiff): Split up either comments or approvals into their own "duck".
export const commentsByApprovalName = createSelector(
    comments,
    (comments) => {
      const map = new Map();
      comments.forEach((comment) => {
        const key = (comment.approvalRef && comment.approvalRef.fieldName) ||
          '';
        if (map.has(key)) {
          map.get(key).push(comment);
        } else {
          map.set(key, [comment]);
        }
      });
      return map;
    },
);

export const fieldValues = createSelector(
    viewedIssue,
    (issue) => issue && issue.fieldValues,
);

export const labelRefs = createSelector(
    viewedIssue,
    (issue) => issue && issue.labelRefs,
);

export const type = createSelector(
    fieldValues,
    labelRefs,
    (fieldValues, labelRefs) => extractTypeForIssue(fieldValues, labelRefs),
);

export const restrictions = createSelector(
    labelRefs,
    (labelRefs) => {
      if (!labelRefs) return {};

      const restrictions = {};

      labelRefs.forEach((labelRef) => {
        const label = labelRef.label;
        const lowerCaseLabel = label.toLowerCase();

        if (lowerCaseLabel.startsWith(RESTRICT_VIEW_PREFIX)) {
          const permissionType = removePrefix(label, RESTRICT_VIEW_PREFIX);
          if (!('view' in restrictions)) {
            restrictions['view'] = [permissionType];
          } else {
            restrictions['view'].push(permissionType);
          }
        } else if (lowerCaseLabel.startsWith(RESTRICT_EDIT_PREFIX)) {
          const permissionType = removePrefix(label, RESTRICT_EDIT_PREFIX);
          if (!('edit' in restrictions)) {
            restrictions['edit'] = [permissionType];
          } else {
            restrictions['edit'].push(permissionType);
          }
        } else if (lowerCaseLabel.startsWith(RESTRICT_COMMENT_PREFIX)) {
          const permissionType = removePrefix(label, RESTRICT_COMMENT_PREFIX);
          if (!('comment' in restrictions)) {
            restrictions['comment'] = [permissionType];
          } else {
            restrictions['comment'].push(permissionType);
          }
        }
      });

      return restrictions;
    },
);

export const isOpen = createSelector(
    viewedIssue,
    (issue) => issue && issue.statusRef && issue.statusRef.meansOpen || false);

// Returns a function that, given an issue and its related issues,
// returns a combined list of issue ref strings including related issues,
// blocking or blocked on issues, and federated references.
const mapRefsWithRelated = (blocking) => {
  return (issue, relatedIssues) => {
    let refs = [];
    if (blocking) {
      if (issue.blockingIssueRefs) {
        refs = refs.concat(issue.blockingIssueRefs);
      }
      if (issue.danglingBlockingRefs) {
        refs = refs.concat(issue.danglingBlockingRefs);
      }
    } else {
      if (issue.blockedOnIssueRefs) {
        refs = refs.concat(issue.blockedOnIssueRefs);
      }
      if (issue.danglingBlockedOnRefs) {
        refs = refs.concat(issue.danglingBlockedOnRefs);
      }
    }

    // Note: relatedIssues is a Redux generated key for issues, not part of the
    // pRPC Issue object.
    if (issue.relatedIssues) {
      refs = refs.concat(issue.relatedIssues);
    }
    return refs.map((ref) => {
      const key = issueRefToString(ref);
      if (relatedIssues.has(key)) {
        return relatedIssues.get(key);
      }
      return ref;
    });
  };
};

export const blockingIssues = createSelector(
    viewedIssue, relatedIssues,
    mapRefsWithRelated(true),
);

export const blockedOnIssues = createSelector(
    viewedIssue, relatedIssues,
    mapRefsWithRelated(false),
);

export const mergedInto = createSelector(
    viewedIssue, relatedIssues,
    (issue, relatedIssues) => {
      if (!issue || !issue.mergedIntoIssueRef) return {};
      const key = issueRefToString(issue.mergedIntoIssueRef);
      if (relatedIssues && relatedIssues.has(key)) {
        return relatedIssues.get(key);
      }
      return issue.mergedIntoIssueRef;
    },
);

export const sortedBlockedOn = createSelector(
    blockedOnIssues,
    (blockedOn) => blockedOn.sort((a, b) => {
      const aIsOpen = a.statusRef && a.statusRef.meansOpen ? 1 : 0;
      const bIsOpen = b.statusRef && b.statusRef.meansOpen ? 1 : 0;
      return bIsOpen - aIsOpen;
    }),
);

// values (from issue.fieldValues) is an array with one entry per value.
// We want to turn this into a map of fieldNames -> values.
export const fieldValueMap = createSelector(
    fieldValues,
    (fieldValues) => fieldValuesToMap(fieldValues),
);

// Get the list of full componentDefs for the viewed issue.
export const components = createSelector(
    viewedIssue,
    projectV0.componentsMap,
    (issue, components) => {
      if (!issue || !issue.componentRefs) return [];
      return issue.componentRefs.map(
          (comp) => components.get(comp.path) || comp);
    },
);

// Get custom fields that apply to a specific issue.
export const fieldDefs = createSelector(
    projectV0.fieldDefs,
    type,
    fieldValueMap,
    (fieldDefs, type, fieldValues) => {
      if (!fieldDefs) return [];
      type = type || '';
      return fieldDefs.filter((f) => {
        const fieldValueKey = fieldValueMapKey(f.fieldRef.fieldName,
            f.phaseRef && f.phaseRef.phaseName);
        if (fieldValues && fieldValues.has(fieldValueKey)) {
        // Regardless of other checks, include a particular field def if the
        // issue has a value defined.
          return true;
        }
        // Skip approval type and phase fields here.
        if (f.fieldRef.approvalName ||
            f.fieldRef.type === fieldTypes.APPROVAL_TYPE ||
            f.isPhaseField) {
          return false;
        }

        // If this fieldDef belongs to only one type, filter out the field if
        // that type isn't the specified type.
        if (f.applicableType && type.toLowerCase() !==
            f.applicableType.toLowerCase()) {
          return false;
        }

        return true;
      });
    },
);

// Action Creators
/**
 * Tells Redux that the user has navigated to an issue page and is now
 * viewing a new issue.
 * @param {IssueRef} issueRef The issue that the user is viewing.
 * @return {AnyAction}
 */
export const viewIssue = (issueRef) => ({type: VIEW_ISSUE, issueRef});

export const fetchCommentReferences = (comments, projectName) => {
  return async (dispatch) => {
    dispatch({type: FETCH_COMMENT_REFERENCES_START});

    try {
      const refs = await autolink.getReferencedArtifacts(comments, projectName);
      const commentRefs = {};
      refs.forEach(({componentName, existingRefs}) => {
        commentRefs[componentName] = existingRefs;
      });
      dispatch({
        type: FETCH_COMMENT_REFERENCES_SUCCESS,
        commentReferences: commentRefs,
      });
    } catch (error) {
      dispatch({type: FETCH_COMMENT_REFERENCES_FAILURE, error});
    }
  };
};

export const fetchReferencedUsers = (issue) => async (dispatch) => {
  if (!issue) return;
  dispatch({type: FETCH_REFERENCED_USERS_START});

  // TODO(zhangtiff): Make this function account for custom fields
  // of type user.
  const userRefs = [...(issue.ccRefs || [])];
  if (issue.ownerRef) {
    userRefs.push(issue.ownerRef);
  }
  (issue.approvalValues || []).forEach((approval) => {
    userRefs.push(...(approval.approverRefs || []));
    if (approval.setterRef) {
      userRefs.push(approval.setterRef);
    }
  });

  try {
    const resp = await prpcClient.call(
        'monorail.Users', 'ListReferencedUsers', {userRefs});

    const referencedUsers = {};
    (resp.users || []).forEach((user) => {
      referencedUsers[user.displayName] = user;
    });
    dispatch({type: FETCH_REFERENCED_USERS_SUCCESS, referencedUsers});
  } catch (error) {
    dispatch({type: FETCH_REFERENCED_USERS_FAILURE, error});
  }
};

export const fetchFederatedReferences = (issue) => async (dispatch) => {
  dispatch({type: FETCH_FEDERATED_REFERENCES_START});

  // Concat all potential fedrefs together, convert from shortlink to classes,
  // then fire off a request to fetch the status of each.
  const fedRefs = []
      .concat(issue.danglingBlockingRefs || [])
      .concat(issue.danglingBlockedOnRefs || [])
      .concat(issue.mergedIntoIssueRef ? [issue.mergedIntoIssueRef] : [])
      .filter((ref) => ref && ref.extIdentifier)
      .map((ref) => fromShortlink(ref.extIdentifier))
      .filter((fedRef) => fedRef);

  // If no FedRefs, return empty Map.
  if (fedRefs.length === 0) {
    return;
  }

  try {
    // Load email separately since it might have changed.
    await loadGapi();
    const email = await fetchGapiEmail();

    // If already logged in, dispatch login success event.
    dispatch({
      type: userV0.GAPI_LOGIN_SUCCESS,
      email: email,
    });

    await Promise.all(fedRefs.map((fedRef) => fedRef.getFederatedDetails()));
    const fedRefIssueRefs = fedRefs.map((fedRef) => fedRef.toIssueRef());

    dispatch({
      type: FETCH_FEDERATED_REFERENCES_SUCCESS,
      fedRefIssueRefs: fedRefIssueRefs,
    });
  } catch (error) {
    dispatch({type: FETCH_FEDERATED_REFERENCES_FAILURE, error});
  }
};

// TODO(zhangtiff): Figure out if we can reduce request/response sizes by
// diffing issues to fetch against issues we already know about to avoid
// fetching duplicate info.
export const fetchRelatedIssues = (issue) => async (dispatch) => {
  if (!issue) return;
  dispatch({type: FETCH_RELATED_ISSUES_START});

  const refsToFetch = (issue.blockedOnIssueRefs || []).concat(
      issue.blockingIssueRefs || []);
  // Add mergedinto ref, exclude FedRefs which are fetched separately.
  if (issue.mergedIntoIssueRef && !issue.mergedIntoIssueRef.extIdentifier) {
    refsToFetch.push(issue.mergedIntoIssueRef);
  }

  const message = {
    issueRefs: refsToFetch,
  };
  try {
    // Fire off call to fetch FedRefs. Since it might take longer it is
    // handled by a separate reducer.
    dispatch(fetchFederatedReferences(issue));

    const resp = await prpcClient.call(
        'monorail.Issues', 'ListReferencedIssues', message);

    const relatedIssues = {};

    const openIssues = resp.openRefs || [];
    const closedIssues = resp.closedRefs || [];
    openIssues.forEach((issue) => {
      issue.statusRef.meansOpen = true;
      relatedIssues[issueRefToString(issue)] = issue;
    });
    closedIssues.forEach((issue) => {
      issue.statusRef.meansOpen = false;
      relatedIssues[issueRefToString(issue)] = issue;
    });
    dispatch({
      type: FETCH_RELATED_ISSUES_SUCCESS,
      relatedIssues: relatedIssues,
    });
  } catch (error) {
    dispatch({type: FETCH_RELATED_ISSUES_FAILURE, error});
  };
};

/**
 * Fetches issue data needed to display a detailed view of a single
 * issue. This function dispatches many actions to handle the fetching
 * of issue comments, permissions, star state, and more.
 * @param {IssueRef} issueRef The issue that the user is viewing.
 * @return {function(function): Promise<void>}
 */
export const fetchIssuePageData = (issueRef) => async (dispatch) => {
  dispatch(fetchComments(issueRef));
  dispatch(fetch(issueRef));
  dispatch(fetchPermissions(issueRef));
  dispatch(fetchIsStarred(issueRef));
};

/**
 * @param {IssueRef} issueRef Which issue to fetch.
 * @return {function(function): Promise<void>}
 */
export const fetch = (issueRef) => async (dispatch) => {
  dispatch({type: FETCH_START});

  try {
    const resp = await prpcClient.call(
        'monorail.Issues', 'GetIssue', {issueRef},
    );

    const movedToRef = resp.movedToRef;

    // The API can return deleted issue objects that don't have issueRef data
    // specified. For this case, we want to make sure a projectName and localId
    // are still provided to the frontend to ensure that keying issues still
    // works.
    const issue = {...issueRef, ...resp.issue};
    if (movedToRef) {
      issue.movedToRef = movedToRef;
    }

    dispatch({type: FETCH_SUCCESS, issue});

    if (!issue.isDeleted && !movedToRef) {
      dispatch(fetchRelatedIssues(issue));
      dispatch(fetchHotlists(issueRef));
      dispatch(fetchReferencedUsers(issue));
      dispatch(userV0.fetchProjects([issue.reporterRef]));
    }
  } catch (error) {
    dispatch({type: FETCH_FAILURE, error});
  }
};

/**
 * Action creator to fetch multiple Issues.
 * @param {Array<IssueRef>} issueRefs An Array of Issue references to fetch.
 * @return {function(function): Promise<void>}
 */
export const fetchIssues = (issueRefs) => async (dispatch) => {
  dispatch({type: FETCH_ISSUES_START});

  try {
    const {openRefs, closedRefs} = await prpcClient.call(
        'monorail.Issues', 'ListReferencedIssues', {issueRefs});
    const issues = [...openRefs || [], ...closedRefs || []];

    dispatch({type: FETCH_ISSUES_SUCCESS, issues});
  } catch (error) {
    dispatch({type: FETCH_ISSUES_FAILURE, error});
  }
};

/**
 * Gets the hotlists that a given issue is in.
 * @param {IssueRef} issueRef
 * @return {function(function): Promise<void>}
 */
export const fetchHotlists = (issueRef) => async (dispatch) => {
  dispatch({type: FETCH_HOTLISTS_START});

  try {
    const resp = await prpcClient.call(
        'monorail.Features', 'ListHotlistsByIssue', {issue: issueRef});

    const hotlists = (resp.hotlists || []);
    hotlists.sort((hotlistA, hotlistB) => {
      return hotlistA.name.localeCompare(hotlistB.name);
    });
    dispatch({type: FETCH_HOTLISTS_SUCCESS, hotlists});
  } catch (error) {
    dispatch({type: FETCH_HOTLISTS_FAILURE, error});
  };
};

/**
 * Async action creator to fetch issues in the issue list and grid pages. This
 * action creator supports batching multiple async requests to support the grid
 * view's ability to load up to 6,000 issues in one page load.
 *
 * @param {string} projectName The project to fetch issues from.
 * @param {Object} params Options for which issues to fetch.
 * @param {string=} params.q The query string for the search.
 * @param {string=} params.can The ID of the canned query for the search.
 * @param {string=} params.groupby The spec of which fields to group by.
 * @param {string=} params.sort The spec of which fields to sort by.
 * @param {number=} params.start What cursor index to start at.
 * @param {number=} params.maxItems How many items to fetch per page.
 * @param {number=} params.maxCalls The maximum number of API calls to make.
 *   Combined with pagination.maxItems, this defines the maximum number of
 *   issues this method can fetch.
 * @return {function(function): Promise<void>}
 */
export const fetchIssueList =
  (projectName, {q = undefined, can = undefined, groupby = undefined,
    sort = undefined, start = undefined, maxItems = undefined,
    maxCalls = 1,
  }) => async (dispatch) => {
    let updateData = {};
    const promises = [];
    const issuesByRequest = [];
    let issueLimit;
    let totalIssues;
    let totalCalls;
    const itemsPerCall = maxItems || 1000;

    const cannedQuery = Number.parseInt(can) || undefined;

    const pagination = {
      ...(start && {start}),
      ...(maxItems && {maxItems}),
    };

    const message = {
      projectNames: [projectName],
      query: q,
      cannedQuery,
      groupBySpec: groupby,
      sortSpec: sort,
      pagination,
    };

    dispatch({type: FETCH_ISSUE_LIST_START});

    // initial api call made to determine total number of issues matching
    // the query.
    try {
      // TODO(zhangtiff): Refactor this action creator when adding issue
      // list pagination.
      const resp = await prpcClient.call(
          'monorail.Issues', 'ListIssues', message);

      // prpcClient is not actually a protobuf client and therefore not
      // hydrating default values. See crbug.com/monorail/6641
      // Until that is fixed, we have to explicitly define it.
      const defaultFetchListResponse = {totalResults: 0, issues: []};

      updateData =
        Object.entries(resp).length === 0 ?
          defaultFetchListResponse :
          resp;
      issuesByRequest[0] = updateData.issues;
      issueLimit = updateData.totalResults;

      // determine correct issues to load and number of calls to be made.
      if (issueLimit > (itemsPerCall * maxCalls)) {
        totalIssues = itemsPerCall * maxCalls;
        totalCalls = maxCalls - 1;
      } else {
        totalIssues = issueLimit;
        totalCalls = Math.ceil(issueLimit / itemsPerCall) - 1;
      }

      if (totalIssues) {
        updateData.progress = updateData.issues.length / totalIssues;
      } else {
        updateData.progress = 1;
      }

      dispatch({type: FETCH_ISSUE_LIST_UPDATE, ...updateData});

      // remaining api calls are made.
      for (let i = 1; i <= totalCalls; i++) {
        promises[i - 1] = (async () => {
          const resp = await prpcClient.call(
              'monorail.Issues', 'ListIssues', {
                ...message,
                pagination: {start: i * itemsPerCall, maxItems: itemsPerCall},
              });
          issuesByRequest[i] = (resp.issues || []);
          // sort the issues in the correct order.
          updateData.issues = [];
          issuesByRequest.forEach((issue) => {
            updateData.issues = updateData.issues.concat(issue);
          });
          updateData.progress = updateData.issues.length / totalIssues;
          dispatch({type: FETCH_ISSUE_LIST_UPDATE, ...updateData});
        })();
      }

      await Promise.all(promises);

      // TODO(zhangtiff): Try to delete FETCH_ISSUE_LIST_SUCCESS in favor of
      // just FETCH_ISSUE_LIST_UPDATE.
      dispatch({type: FETCH_ISSUE_LIST_SUCCESS});
    } catch (error) {
      dispatch({type: FETCH_ISSUE_LIST_FAILURE, error});
    };
  };

/**
 * Fetches the currently logged in user's permissions for a given issue.
 * @param {Issue} issueRef
 * @return {function(function): Promise<void>}
 */
export const fetchPermissions = (issueRef) => async (dispatch) => {
  dispatch({type: FETCH_PERMISSIONS_START});

  try {
    const resp = await prpcClient.call(
        'monorail.Issues', 'ListIssuePermissions', {issueRef},
    );

    dispatch({type: FETCH_PERMISSIONS_SUCCESS, permissions: resp.permissions});
  } catch (error) {
    dispatch({type: FETCH_PERMISSIONS_FAILURE, error});
  };
};

/**
 * Fetches comments for an issue. Note that issue descriptions are also
 * comments.
 * @param {IssueRef} issueRef
 * @return {function(function): Promise<void>}
 */
export const fetchComments = (issueRef) => async (dispatch) => {
  dispatch({type: FETCH_COMMENTS_START});

  try {
    const resp = await prpcClient.call(
        'monorail.Issues', 'ListComments', {issueRef});

    dispatch({type: FETCH_COMMENTS_SUCCESS, comments: resp.comments});
    dispatch(fetchCommentReferences(
        resp.comments, issueRef.projectName));

    const commenterRefs = (resp.comments || []).map(
        (comment) => comment.commenter);
    dispatch(userV0.fetchProjects(commenterRefs));
  } catch (error) {
    dispatch({type: FETCH_COMMENTS_FAILURE, error});
  };
};

/**
 * Gets whether the logged in user has starred a given issue.
 * @param {IssueRef} issueRef
 * @return {function(function): Promise<void>}
 */
export const fetchIsStarred = (issueRef) => async (dispatch) => {
  dispatch({type: FETCH_IS_STARRED_START});
  try {
    const resp = await prpcClient.call(
        'monorail.Issues', 'IsIssueStarred', {issueRef},
    );

    dispatch({
      type: FETCH_IS_STARRED_SUCCESS,
      starred: resp.isStarred,
      issueRef: issueRef,
    });
  } catch (error) {
    dispatch({type: FETCH_IS_STARRED_FAILURE, error});
  };
};

/**
 * Fetch all of a logged in user's starred issues.
 * @return {function(function): Promise<void>}
 */
export const fetchStarredIssues = () => async (dispatch) => {
  dispatch({type: FETCH_ISSUES_STARRED_START});

  try {
    const resp = await prpcClient.call(
        'monorail.Issues', 'ListStarredIssues', {},
    );
    dispatch({type: FETCH_ISSUES_STARRED_SUCCESS,
      starredIssueRefs: resp.starredIssueRefs});
  } catch (error) {
    dispatch({type: FETCH_ISSUES_STARRED_FAILURE, error});
  };
};

/**
 * Stars or unstars an issue.
 * @param {IssueRef} issueRef The issue to star.
 * @param {boolean} starred Whether to star or unstar.
 * @return {function(function): Promise<void>}
 */
export const star = (issueRef, starred) => async (dispatch) => {
  const requestKey = issueRefToString(issueRef);

  dispatch({type: STAR_START, requestKey});
  const message = {issueRef, starred};

  try {
    const resp = await prpcClient.call(
        'monorail.Issues', 'StarIssue', message,
    );

    dispatch({
      type: STAR_SUCCESS,
      starCount: resp.starCount,
      issueRef,
      starred,
      requestKey,
    });
  } catch (error) {
    dispatch({type: STAR_FAILURE, error, requestKey});
  }
};

/**
 * Runs a presubmit request to find warnings to show the user before an issue
 * edit is saved.
 * @param {IssueRef} issueRef The issue being edited.
 * @param {IssueDelta} issueDelta The user's in flight changes to the issue.
 * @return {function(function): Promise<void>}
 */
export const presubmit = (issueRef, issueDelta) => async (dispatch) => {
  dispatch({type: PRESUBMIT_START});

  try {
    const resp = await prpcClient.call(
        'monorail.Issues', 'PresubmitIssue', {issueRef, issueDelta});

    dispatch({type: PRESUBMIT_SUCCESS, presubmitResponse: resp});
  } catch (error) {
    dispatch({type: PRESUBMIT_FAILURE, error: error});
  }
};

/**
 * Async action creator to update an issue's approval.
 *
 * @param {Object} params Options for the approval update.
 * @param {IssueRef} params.issueRef
 * @param {FieldRef} params.fieldRef
 * @param {ApprovalDelta=} params.approvalDelta
 * @param {string=} params.commentContent
 * @param {boolean=} params.sendEmail
 * @param {boolean=} params.isDescription
 * @param {AttachmentUpload=} params.uploads
 * @return {function(function): Promise<void>}
 */
export const updateApproval = ({issueRef, fieldRef, approvalDelta,
  commentContent, sendEmail, isDescription, uploads}) => async (dispatch) => {
  dispatch({type: UPDATE_APPROVAL_START});
  try {
    const {approval} = await prpcClient.call(
        'monorail.Issues', 'UpdateApproval', {
          ...(issueRef && {issueRef}),
          ...(fieldRef && {fieldRef}),
          ...(approvalDelta && {approvalDelta}),
          ...(commentContent && {commentContent}),
          ...(sendEmail && {sendEmail}),
          ...(isDescription && {isDescription}),
          ...(uploads && {uploads}),
        });

    dispatch({type: UPDATE_APPROVAL_SUCCESS, approval, issueRef});
    dispatch(fetch(issueRef));
    dispatch(fetchComments(issueRef));
  } catch (error) {
    dispatch({type: UPDATE_APPROVAL_FAILURE, error: error});
  };
};

/**
 * Async action creator to update an issue.
 *
 * @param {Object} params Options for the issue update.
 * @param {IssueRef} params.issueRef
 * @param {IssueDelta=} params.delta
 * @param {string=} params.commentContent
 * @param {boolean=} params.sendEmail
 * @param {boolean=} params.isDescription
 * @param {AttachmentUpload=} params.uploads
 * @param {Array<number>=} params.keptAttachments
 * @return {function(function): Promise<void>}
 */
export const update = ({issueRef, delta, commentContent, sendEmail,
  isDescription, uploads, keptAttachments}) => async (dispatch) => {
  dispatch({type: UPDATE_START});

  try {
    const {issue} = await prpcClient.call(
        'monorail.Issues', 'UpdateIssue', {issueRef, delta,
          commentContent, sendEmail, isDescription, uploads,
          keptAttachments});

    dispatch({type: UPDATE_SUCCESS, issue});
    dispatch(fetchComments(issueRef));
    dispatch(fetchRelatedIssues(issue));
    dispatch(fetchReferencedUsers(issue));
  } catch (error) {
    dispatch({type: UPDATE_FAILURE, error: error});
  };
};

/**
 * Converts an issue from one template to another. This is used for changing
 * launch issues.
 * @param {IssueRef} issueRef
 * @param {Object} options
 * @param {string=} options.templateName
 * @param {string=} options.commentContent
 * @param {boolean=} options.sendEmail
 * @return {function(function): Promise<void>}
 */
export const convert = (issueRef, {templateName = '',
  commentContent = '', sendEmail = true},
) => async (dispatch) => {
  dispatch({type: CONVERT_START});

  try {
    const resp = await prpcClient.call(
        'monorail.Issues', 'ConvertIssueApprovalsTemplate',
        {issueRef, templateName, commentContent, sendEmail});

    dispatch({type: CONVERT_SUCCESS, issue: resp.issue});
    const fetchCommentsMessage = {issueRef};
    dispatch(fetchComments(fetchCommentsMessage));
  } catch (error) {
    dispatch({type: CONVERT_FAILURE, error: error});
  };
};
