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

/* eslint-disable no-unused-vars */

const COMMENT_TYPE_DESCRIPTION = 'DESCRIPTION';

/**
 * Fetches the issue from Monorail.
 * @param {string} issueName The resource name of the issue.
 * @return {Issue}
 */
function getIssue(issueName) {
  const message = {'name': issueName};
  const url = URL + 'monorail.v3.Issues/GetIssue';
  return run_(url, message);
}

/**
 * Fetches all the given issues from Monorail.
 * @param {Array<string>} issueNames The resource names of the issues.
 * @return {Array<Issue>}
 */
function batchGetIssues(issueNames) {
  const message = {'names': issueNames};
  const url = URL + 'monorail.v3.Issues/BatchGetIssues';
  return run_(url, message);
}

/**
 * Fetches all the ApprovalValues that belong to the given issue.
 * @param {string} issueName The resource name of the issue.
 * @return {Array<ApprovalValue>}
 */
function listApprovalValues(issueName) {
  const message = {'parent': issueName};
  const url = URL + 'monorail.v3.Issues/ListApprovalValues';
  return run_(url, message);
}

/**
 * Calls SearchIssues with the given parameters.
 * @param {Array<string>} projectNames resource names of the projects to search.
 * @param {string} query The query to use to search.
 * @param {string} orderBy The issue fields to order issues by.
 * @param {Number} pageSize The maximum issues to return.
 * @param {string} pageToken The page token from the previous call.
 * @return {Array<SearchIssuesResponse>}
 */
function searchIssuesPagination_(
    projectNames, query, orderBy, pageSize, pageToken) {
  const message = {
    'projects': projectNames,
    'query': query,
    'orderBy': orderBy,
    'pageToken': pageToken};
  if (pageSize) {
    message['pageSize'] = pageSize;
  }
  const url = URL + 'monorail.v3.Issues/SearchIssues';
  return run_(url, message);
}

// TODO(crbug.com/monorail/7143): SearchIssues only accepts one project.
/**
 * Searches Monorail for issues using the given query.
 * NOTE: We currently only accept `projectNames` with one and only one project.
 * @param {Array<string>} projects Resource names of the projects to search
 *     within.
 * @param {string=} query The query to use to search.
 * @param {string=} orderBy The issue fields to order issues by,
 *    e.g. 'EstDays,Opened,-stars'
 * @return {Array<Issue>}
 */
function searchIssues(projects, query, orderBy) {
  const pageSize = 100;
  let pageToken;

  issues = [];

  do {
    const resp = searchIssuesPagination_(
        projects, query, orderBy, pageSize, pageToken);
    issues = issues.concat(resp.issues);
    pageToken = resp.nextPageToken;
  }
  while (pageToken);

  return issues;
}

/**
 * Calls ListComments with the given parameters.
 * @param {string} issueName Resource name of the issue.
 * @param {string} filter The approval filter query.
 * @param {Number} pageSize The maximum number of comments to return.
 * @param {string} pageToken The page token from the previous request.
 * @return {ListCommentsResponse}
 */
function listCommentsPagination_(issueName, filter, pageSize, pageToken) {
  const message = {
    'parent': issueName,
    'pageToken': pageToken,
    'filter': filter,
  };
  if (pageSize) {
    message['pageSize'] = pageSize;
  }
  const url = URL + 'monorail.v3.Issues/ListComments';
  return run_(url, message);
}

/**
 * Returns all comments and previous/current descriptions of an issue.
 * @param {string} issueName Resource name of the Issue.
 * @param {string=} filter The filter query filtering out comments.
 *     We only accept `approval = "<approvalDef resource name>""`.
 *     e.g. 'approval = "projects/chromium/approvalDefs/34"'
 * @return {Array<Comment>}
 */
function listComments(issueName, filter) {
  let pageToken;

  let comments = [];
  do {
    const resp = listCommentsPagination_(issueName, filter, '', pageToken);
    comments = comments.concat(resp.comments);
    pageToken = resp.nextPageToken;
  }
  while (pageToken);

  return comments;
}

/**
 * Gets the current description of an issue.
 * @param {string} issueName Resource name of the Issue.
 * @param {string=} filter The filter query filtering out comments.
 *     We only accept `approval = "<approvalDef resource name>""`.
 *     e.g. 'approval = "projects/chromium/approvalDefs/34"'
 * @return {Comment}
 */
function getCurrentDescription(issueName, filter) {
  const allComments = listComments(issueName, filter);
  for (let i = (allComments.length - 1); i > -1; i--) {
    if (allComments[i].type === COMMENT_TYPE_DESCRIPTION) {
      return allComments[i];
    }
  }
}

/**
 * Gets the first (non-description) comment of an issue.
 * @param {string} issueName Resource name of the Issue.
 * @param {string=} filter The filter query filtering out comments.
 *     We only accept `approval = "<approvalDef resource name>""`.
 *      e.g. 'approval = "projects/chromium/approvalDefs/34"'
 * @return {Comment}
 */
function getFirstComment(issueName, filter) {
  const allComments = listComments(issueName, filter);
  for (let i = 0; i < allComments.length; i++) {
    if (allComments[i].type !== COMMENT_TYPE_DESCRIPTION) {
      return allComments[i];
    }
  }
  return null;
}

/**
 * Gets the last (non-description) comment of an issue.
 * @param {string} issueName The resource name of the issue.
 * @param {string=} filter The filter query filtering out comments.
 *     We only accept `approval = "<approvalDef resource name>""`.
 *     e.g. 'approval = "projects/chromium/approvalDefs/34"'
 * @return {Issue}
 */
function getLastComment(issueName, filter) {
  const allComments = listComments(issueName, filter);
  for (let i = (allComments.length - 1); i > -1; i--) {
    if (allComments[i].type != COMMENT_TYPE_DESCRIPTION) {
      return allComments[i];
    }
  }
  return null;
}

/**
 * Checks if the given label exists in the issue.
 * @param {Issue} issue The issue to search within for the label.
 * @param {string} label The label to search for.
 * @return {boolean}
 */
function hasLabel(issue, label) {
  if (issue.labels) {
    const testLabel = label.toLowerCase();
    return issue.labels.some(({label}) => testLabel === label.toLowerCase());
  }
  return false;
}

/**
 * Checks if the issue has any labels matching the given regex.
 * @param {Issue} issue The issue to search within for matching labels.
 * @param {string} regex The regex pattern to use to search for labels.
 * @return {boolean}
 */
function hasLabelMatching(issue, regex) {
  if (issue.labels) {
    const re = new RegExp(regex, 'i');
    return issue.labels.some(({label}) => re.test(label));
  }
  return false;
}

/**
 * Returns all labels in the issue that match the given regex.
 * @param {Issue} issue The issue to search within for matching labels.
 * @param {string} regex The regex pattern to use to search for labels.
 * @return {Array<string>}
 */
function getLabelsMatching(issue, regex) {
  const labels = [];
  if (issue.labels) {
    const re = new RegExp(regex, 'i');
    for (let i = 0; i < issue.labels.length; i++) {
      if (re.test(issue.labels[i].label)) {
        labels.push(issue.labels[i].label);
      }
    }
  }
  return labels;
}

/**
 * Get the comment where the given label was added, if any.
 * @param {string} issueName The resource name of the issue.
 * @param {string} label The label that was remove.
 * @return {Comment}
 */
function getLabelSetComment(issueName, label) {
  const comments = listComments(issueName);
  for (let i = 0; i < comments.length; i++) {
    const comment = comments[i];
    if (comment.amendments) {
      for (let j = 0; j < comment.amendments.length; j++) {
        const amendment = comment.amendments[j];
        if (amendment['fieldName'] === 'Labels' &&
            amendment['newOrDeltaValue'].toLowerCase() === (
              label.toLocaleLowerCase())) {
          return comment;
        }
      }
    }
  }
  return null;
}

/**
 * Get the comment where the given label was removed, if any.
 * @param {string} issueName The resource name of the issue.
 * @param {string} label The label that was remove.
 * @return {Comment}
 */
function getLabelRemoveComment(issueName, label) {
  const comments = listComments(issueName);
  for (let i = 0; i < comments.length; i++) {
    const comment = comments[i];
    if (comment.amendments) {
      for (let j = 0; j < comment.amendments.length; j++) {
        const amendment = comment.amendments[j];
        if (amendment['fieldName'] === 'Labels' &&
            amendment[
                'newOrDeltaValue'].toLowerCase() === (
              '-' + label.toLocaleLowerCase())) {
          return comment;
        }
      }
    }
  }
  return null;
}

/**
 * Updates the issue to have the given label added.
 * This method does not call Monorail's API to save this change.
 * Call saveChanges() to send all updates to Monorail.
 * @param {Issue} issue The issue to update.
 * @param {string} label The label to add.
 */
function addLabel(issue, label) {
  if (hasLabel(issue, label)) return;
  maybeCreateDelta_(issue);
  // Add the label to the issue's delta.labelsAdd.
  issue.delta.labelsAdd.push(label);
  // Add the label to the issue.
  issue.labels.push({label: label});
  // 'labels' added to updateMask in saveChanges().
}

/**
 * Updates the issue to have the given label removed from the issue.
 * This method does not call Monorail's API to save this change.
 * Call saveChanges() to send all updates to Monorail.
 * @param {Issue} issue The issue to update.
 * @param {string} label The label to remove.
 */
function removeLabel(issue, label) {
  if (!hasLabel(issue, label)) return;
  maybeCreateDelta_(issue);
  // Add the label to the issue's delta.labelsRemove.
  issue.delta.labelsRemove.push(label);
  // Remove label from issue.
  for (let i = 0; i < issue.labels.length; i++) {
    if (issue.labels[i].label.toLowerCase() === label.toLowerCase()) {
      issue.labels.splice(i, 1);
      break;
    }
  }
}

/**
 * Sets the owner of the given issue.
 * This method does not call Monorail's API to save this change.
 * Call saveChanges() to send all updates to Monorail.
 * @param {Issue} issue Issue to change.
 * @param {string} ownerName The resource name of the new owner,
 *     e.g. 'users/chicken@email.com'
*/
function setOwner(issue, ownerName) {
  maybeCreateDelta_(issue);
  issue.owner = {'user': ownerName};
  if (issue.delta.updateMask.indexOf('owner.user') === -1) {
    issue.delta.updateMask.push('owner.user');
  }
}

/**
 * Sets the summary of the given issue.
 * This method does not call Monorail's API to save this change.
 * Call saveChanges() to send all updates to Monorail.
 * @param {Issue} issue Issue to change.
 * @param {string} summary The new summary of the issue.
*/
function setSummary(issue, summary) {
  maybeCreateDelta_(issue);
  issue.summary = summary;
  if (issue.delta.updateMask.indexOf('summary') === -1) {
    issue.delta.updateMask.push('summary');
  }
}

/**
 *Sets the status of the given issue.
 * This method does not call Monorail's API to save this change.
 * Call saveChanges() to send all updates to Monorail.
 * @param {Issue} issue Issue to change.
 * @param {string} status The new status of the issue e.g. 'Available'.
*/
function setStatus(issue, status) {
  maybeCreateDelta_(issue);
  issue.status.status = status;
  if (issue.delta.updateMask.indexOf('status.status') === -1) {
    issue.delta.updateMask.push('status.status');
  }
}

/**
 * Sets the merged into issue for the given issue.
 * This method does not call Monorail's API to save this change.
 * Call saveChanges() to send all updates to Monorail.
 * @param {Issue} issue Issue to change.
 * @param {IssueRef} mergedIntoRef IssueRef of the issue to merge into.
 */
function setMergedInto(issue, mergedIntoRef) {
  maybeCreateDelta_(issue);
  issue.mergedIntoIssueRef = mergedIntoRef;
  if (issue.delta.updateMask.indexOf('mergedIntoIssueRef') === -1) {
    issue.delta.updateMask.push('mergedIntoIssueRef');
  }
}

/**
 * Checks if target is found in source.
 * @param {IssueRef} target The IssueRef to look for.
 * @param {Array<IssueRef>} source the IssueRefs to look in.
 * @return {number} index of target in source, -1 if not found.
 */
function issueRefExists_(target, source) {
  for (let i = 0; i < source.length; i++) {
    if ((source[i].issue === target.issue || (!source[i].issue && !target.issue)
    ) && (source[i].extIdentifier === target.extIdentifier || (
      !source[i].extIdentifier && !target.extIdentifier))) {
      return i;
    }
  }
  return -1;
}

/**
 * Makes blocking issue ref changes.
 * blockingIssuesAdd are added before blockingIssuesRemove are removed.
 * This method does not call Monorail's API to save this change.
 * Call saveChanges() to send all updates to Monorail.
 * @param {Issue} issue Issue to change.
 * @param {Array<IssueRef>} blockingIssuesAdd issues to add as blocking issues.
 * @param {Array<IssueRef>} blockingIssuesRemove issues to remove from blocking
 *     issues.
 */
function addBlockingIssueChanges(
    issue, blockingIssuesAdd, blockingIssuesRemove) {
  maybeCreateDelta_(issue);
  blockingIssuesAdd.forEach((addRef) => {
    const iInIssue = issueRefExists_(addRef, issue.blockingIssueRefs);
    if (iInIssue === -1) { // addRef not found in issue
      issue.blockingIssueRefs.push(addRef);
      issue.delta.blockingAdd.push(addRef);
      const iInDeltaRemove = issueRefExists_(
          addRef, issue.delta.blockingRemove);
      if (iInDeltaRemove != -1) {
        // Remove addRef from blckingRemove that may have been added earlier.
        issue.delta.blockingRemove.splice(iInDeltaRemove, 1);
      }
      // issue.delta.updateMask is updated in saveChanges()
    }
  });
  // Add blockingIssuesAdd to issue and issue.delta.blockingAdd if not in
  // issue.blockingIssues
  blockingIssuesRemove.forEach((removeRef) => {
    const iInIssue = issueRefExists_(removeRef, issue.blockingIssueRefs);
    if (iInIssue > -1) {
      issue.blockingIssueRefs.splice(iInIssue, 1);
      issue.delta.blockingRemove.push(removeRef);
      const iInDeltaAdd = issueRefExists_(removeRef, issue.delta.blockingAdd);
      if (iInDeltaAdd != -1) {
        issue.delta.blockingAdd.splice(iInDeltaAdd, 1);
      }
    }
  });
}

/**
 * Makes blocked-on issue ref changes.
 * blockedOnIssuesAdd are added before blockedOnIssuesRemove are removed.
 * This method does not call Monorail's API to save this change.
 * Call saveChanges() to send all updates to Monorail.
 * @param {Issue} issue Issue to change.
 * @param {Array<IssueRef>} blockedOnIssuesAdd issues to add as blockedon
 *     issues.
 * @param {Array<IssueRef>} blockedOnIssuesRemove issues to remove from
 *     blockedon issues.
 */
function addBlockedOnIssueChanges(
    issue, blockedOnIssuesAdd, blockedOnIssuesRemove) {
  maybeCreateDelta_(issue);
  blockedOnIssuesAdd.forEach((addRef) => {
    const iInIssue = issueRefExists_(addRef, issue.blockedOnIssueRefs);
    if (iInIssue === -1) { // addRef not found in issue
      issue.blockedOnIssueRefs.push(addRef);
      issue.delta.blockedOnAdd.push(addRef);
      const iInDeltaRemove = issueRefExists_(
          addRef, issue.delta.blockedOnRemove);
      if (iInDeltaRemove != -1) {
        // Remove addRef from blckingRemove that may have been added earlier.
        issue.delta.blockedOnRemove.splice(iInDeltaRemove, 1);
      }
      // issue.delta.updateMask is updated in saveChanges()
    }
  });
  // Add blockedOnIssuesAdd to issue and issue.delta.blockedOnAdd if not in
  // issue.blockedOnIssues.
  blockedOnIssuesRemove.forEach((removeRef) => {
    const iInIssue = issueRefExists_(removeRef, issue.blockedOnIssueRefs);
    if (iInIssue > -1) {
      issue.blockedOnIssueRefs.splice(iInIssue, 1);
      issue.delta.blockedOnRemove.push(removeRef);
      const iInDeltaAdd = issueRefExists_(removeRef, issue.delta.blockedOnAdd);
      if (iInDeltaAdd != -1) {
        issue.delta.blockedOnAdd.splice(iInDeltaAdd, 1);
      }
    }
  });
}


/**
 * Looks for a component name in an Array of ComponentValues.
 * @param {string} compName Resource name of the Component to look for.
 * @param {Array<ComponentValue>} compArray List of ComponentValues.
 * @return {number} Index of compName in compArray, -1 if not found.
 */
function componentExists_(compName, compArray) {
  for (let i = 0; i < compArray.length; i++) {
    if (compArray[i].component === compName) {
      return i;
    }
  }
  return -1;
}

/**
 * Adds the component changes to the issue.
 * componentNamesAdd are added before componentNamesremove are removed.
 * This method does not call Monorail's API to save this change.
 * Call saveChanges() to send all updates to Monorail.
 * @param {Issue} issue Issue to change.
 * @param {Array<string>} componentNamesAdd Array of component resource names.
 * @param {Array<string>} componentNamesRemove Array or component resource
 *     names.

*/
function addComponentChanges(issue, componentNamesAdd, componentNamesRemove) {
  maybeCreateDelta_(issue);
  componentNamesAdd.forEach((compName) => {
    const iInIssue = componentExists_(compName, issue.components);
    if (iInIssue === -1) { // compName is not in issue.
      issue.components.push({'component': compName});
      issue.delta.componentsAdd.push(compName);
      const iInDeltaRemove = issue.delta.componentsRemove.indexOf(compName);
      if (iInDeltaRemove != -1) {
        // Remove compName from issue.delta.componentsRemove that may have been
        // added before.
        issue.delta.componentsRemove.splice(iInDeltaRemove, 1);
      }
      // issue.delta.updateMask is updated in saveChanges()
    }
  });

  componentNamesRemove.forEach((compName) => {
    const iInIssue = componentExists_(compName, issue.components);
    if (iInIssue != -1) { // compName was found in issue.
      issue.components.splice(iInIssue, 1);
      issue.delta.componentsRemove.push(compName);
      const iInDeltaAdd = issue.delta.componentsAdd.indexOf(compName);
      if (iInDeltaAdd != -1) {
        // Remove compName from issue.delta.componentsAdd that may have been
        // added before.
        issue.delta.componentsAdd.splice(iInDeltaAdd, 1);
      }
    }
  });
}

/**
 * Checks if the fieldVal is found in fieldValsArray
 * @param {FieldValue} fieldVal the field to look for.
 * @param {Array<FieldValue>} fieldValsArray the Array to look within.
 * @return {number} the index of fieldVal in fieldValsArray, or -1 if not found.
 */
function fieldValueExists_(fieldVal, fieldValsArray) {
  for (let i = 0; i < fieldValsArray.length; i++) {
    const currFv = fieldValsArray[i];
    if (currFv.field === fieldVal.field && currFv.value === fieldVal.value && (
      currFv.phase === fieldVal.phase || (
        !currFv.phase && !fieldVal.phase))) {
      return i;
    }
  }
  return -1;
}

/**
 * Adds the FieldValue changes to the issue.
 * fieldValuesAdd are added before fieldValuesRemove are removed.
 * This method does not call Monorail's API to save this change.
 * Call saveChanges() to send all updates to Monorail.
 * @param {Issue} issue Issue to change.
 * @param {Array<FieldValue>} fieldValuesAdd Array of FieldValues to add.
 * @param {Array<FieldValue>} fieldValuesRemove Array of FieldValues to remove.
*/
function addFieldValueChanges(issue, fieldValuesAdd, fieldValuesRemove) {
  maybeCreateDelta_(issue);
  fieldValuesAdd.forEach((fvAdd) => {
    const iInIssue = fieldValueExists_(fvAdd, issue.fieldValues);
    if (iInIssue === -1) { // fvAdd is not already in issue, so we can add it.
      issue.fieldValues.push(fvAdd);
      issue.delta.fieldValuesAdd.push(fvAdd);
      const iInDeltaRemove = fieldValueExists_(
          fvAdd, issue.delta.fieldValuesRemove);
      if (iInDeltaRemove != -1) {
        // fvAdd was added to fieldValuesRemove in a previous call.
        issue.delta.fieldValuesRemove.splice(iInDeltaRemove, 1);
      }
      // issue.delta.updateMask is updated in saveChanges()
    }
  });
  // issue.delta.updateMask is updated in saveChanges()
  fieldValuesRemove.forEach((fvRemove) => {
    const iInIssue = fieldValueExists_(fvRemove, issue.fieldValues);
    if (iInIssue != -1) { // fvRemove is in issue, so we can remove it.
      issue.fieldValues.splice(iInIssue, 1);
      issue.delta.fieldValuesRemove.push(fvRemove);
      const iInDeltaAdd = fieldValueExists_(
          fvRemove, issue.delta.fieldValuesAdd);
      if (iInDeltaAdd != -1) {
        // fvRemove was added to fieldValuesAdd in a previous call.
        issue.delta.fieldValuesAdd.splice(iInDeltaAdd, 1);
      }
    }
  });
}

/**
 * Checks for the existence of userName in userValues
 * @param {string} userName A user resource name to look for.
 * @param {Array<UserValue>} userValues UserValues to search through.
 * @return {number} Index of userName's UserValue in userValues or -1 if not
 *     found.
 */
function userValueExists_(userName, userValues) {
  for (let i = 0; i< userValues.length; i++) {
    if (userValues[i].user === userName) {
      return i;
    }
  }
  return -1;
}

/**
 * Adds the CC changes to the issue.
 * ccNamesAdd are added before ccNamesRemove are removed.
 * This method does not call Monorail's API to save this change.
 * Call saveChanges() to send all updates to Monorail.
 * @param {Issue} issue Issue to change.
 * @param {Array<string>} ccNamesAdd Array if user resource names.
 * @param {Array<string>} ccNamesRemove Array if user resource names.
*/
function addCcChanges(issue, ccNamesAdd, ccNamesRemove) {
  maybeCreateDelta_(issue);
  ccNamesAdd.forEach((ccName) => {
    const iInIssue = userValueExists_(ccName, issue.ccUsers);
    if (iInIssue === -1) { // User is not in issue, so we can add them.
      issue.ccUsers.push({'user': ccName});
      issue.delta.ccsAdd.push(ccName);
      const iInDeltaRemove = issue.delta.ccsRemove.indexOf(ccName);
      if (iInDeltaRemove != -1) {
        // ccName was added to ccsRemove in a previous call.
        issue.delta.ccsRemove.splice(iInDeltaRemove, 1);
      }
    }
  });
  ccNamesRemove.forEach((ccName) => {
    const iInIssue = userValueExists_(ccName, issue.ccUsers);
    if (iInIssue != -1) { // User is in issue, so we can remove it.
      issue.ccUsers.splice(iInIssue, 1);
      issue.delta.ccsRemove.push(ccName);
      const iInDeltaAdd = issue.delta.ccsAdd.indexOf(ccName);
      if (iInDeltaAdd != -1) {
        // ccName was added to delta.ccsAdd in a previous all.
        issue.delta.ccsAdd.splice(iInDeltaAdd, 1);
      }
    }
  });
}

/**
 * Set the pending comment of the issue.
 * @param {Issue} issue Issue whose comment we want to set.
 * @param {string} comment Comment that we want for the issue.
 */
function setComment(issue, comment) {
  maybeCreateDelta_(issue);
  issue.delta.comment = comment;
}

/**
 * Get the pending comment for the issue.
 * @param {Issue} issue Issue whose comment we want.
 * @return {string}
 */
function getPendingComment(issue) {
  if (issue.delta) {
    return issue.delta.comment;
  }
  return '';
}

/**
 * Adds to the existing pending comment
 * @param {Issue} issue Issue to update.
 * @param {string} comment The comment string to add to the existing one.
 */
function appendComment(issue, comment) {
  maybeCreateDelta_(issue);
  issue.delta.comment = issue.delta.comment.concat(comment);
}

/**
 * Sets up an issue for pending changes.
 * @param {Issue} issue The issue that needs to be updated.
 */
function maybeCreateDelta_(issue) {
  if (!issue.delta) {
    issue.delta = newIssueDelta_();
    if (!issue.components) {
      issue.components = [];
    };
    if (!issue.blockingIssueRefs) {
      issue.blockingIssueRefs = [];
    }
    if (!issue.blockedOnIssueRefs) {
      issue.blockedOnIssueRefs = [];
    }
    if (!issue.ccUsers) {
      issue.ccUsers = [];
    }
    if (!issue.labels) {
      issue.labels = [];
    }
    if (!issue.fieldValues) {
      issue.fieldValues = [];
    }
  }
}

/**
 * Creates an IssueDelta
 * @return {IssueDelta_}
 */
function newIssueDelta_() {
  return new IssueDelta_();
}

/** Used to track pending changes to an issue.*/
function IssueDelta_() {
  /** Array<string> */ this.updateMask = [];

  // User resource names.
  /** Array<string> */ this.ccsRemove = [];
  /** Array<string> */ this.ccsAdd = [];

  /** Array<IssueRef> */ this.blockedOnRemove = [];
  /** Array<IssueRef> */ this.blockedOnAdd = [];
  /** Array<IssueRef> */ this.blockingRemove = [];
  /** Array<IssueRef> */ this.blockingAdd = [];

  // Component resource names.
  /** Array<string> */ this.componentsRemove = [];
  /** Array<string> */ this.componentsAdd = [];

  // Label values, e.g. 'Security-Notify'.
  /** Array<string> */ this.labelsRemove = [];
  /** Array<string> */ this.labelsAdd = [];

  /** Array<FieldValue> */ this.fieldValuesRemove = [];
  /** Array<FieldValue> */ this.fieldValuesAdd = [];

  this.comment = '';
}

/**
 * Calls Monorail's API to update the issue.
 * @param {Issue} issue The issue to update where issue['delta'] is expected
 *     to exist.
 * @param {boolean} sendEmail True if the update should trigger email
 *     notifications.
 * @return {Issue}
 */
function saveChanges(issue, sendEmail) {
  if (!issue.delta) {
    throw new Error('No pending changes for issue.');
  }

  const modifyDelta = {
    'ccsRemove': issue.delta.ccsRemove,
    'blockedOnIssuesRemove': issue.delta.blockedOnRemove,
    'blockingIssuesRemove': issue.delta.blockingRemove,
    'componentsRemove': issue.delta.componentsRemove,
    'labelsRemove': issue.delta.labelsRemove,
    'fieldValsRemove': issue.delta.fieldValuesRemove,
    'issue': {
      'name': issue.name,
      'fieldValues': issue.delta.fieldValuesAdd,
      'blockedOnIssueRefs': issue.delta.blockedOnAdd,
      'blockingIssueRefs': issue.delta.blockingAdd,
      'mergedIntoIssueRef': issue.mergedIntoIssueRef,
      'summary': issue.summary,
      'status': issue.status,
      'owner': issue.owner,
      'labels': [],
      'ccUsers': [],
      'components': [],
    },
  };

  if (issue.delta.fieldValuesAdd.length > 0) {
    issue.delta.updateMask.push('fieldValues');
  }

  if (issue.delta.blockedOnAdd.length > 0) {
    issue.delta.updateMask.push('blockedOnIssueRefs');
  }

  if (issue.delta.blockingAdd.length > 0) {
    issue.delta.updateMask.push('blockingIssueRefs');
  }

  if (issue.delta.ccsAdd.length > 0) {
    issue.delta.updateMask.push('ccUsers');
  }
  issue.delta.ccsAdd.forEach((userResourceName) => {
    modifyDelta.issue['ccUsers'].push({'user': userResourceName});
  });

  if (issue.delta.labelsAdd.length > 0) {
    issue.delta.updateMask.push('labels');
  }
  issue.delta.labelsAdd.forEach((label) => {
    modifyDelta.issue['labels'].push({'label': label});
  });

  if (issue.delta.componentsAdd.length > 0) {
    issue.delta.updateMask.push('components');
  }
  issue.delta.componentsAdd.forEach((compResourceName) => {
    modifyDelta.issue['components'].push({'component': compResourceName});
  });

  modifyDelta['updateMask'] = issue.delta.updateMask.join();

  const message = {
    'deltas': [modifyDelta],
    'notifyType': sendEmail ? 'EMAIL' : 'NO_NOTIFICATION',
    'commentContent': issue.delta.comment,
  };

  const url = URL + 'monorail.v3.Issues/ModifyIssues';
  response = run_(url, message);
  if (!response.issues) {
    Logger.log('All changes Noop');
    return null;
  }
  issue = response.issues[0];
  return issue;
}

/**
 * Creates an Issue.
 * @param {string} projectName: Resource name of the parent project.
 * @param {string} summary: Summary of the issue.
 * @param {string} description: Description of the issue.
 * @param {string} status: Status of the issue, e.g. "Untriaged".
 * @param {boolean} sendEmail: True if this should trigger email notifications.
 * @param {string=} ownerName: Resource name of the issue owner.
 * @param {Array<string>=} ccNames: Resource names of the users to cc.
 * @param {Array<string>=} labels: Labels to add to the issue,
 *     e.g. "Restict-View-Google".
 * @param {Array<string>=} componentNames: Resource names of components to add.
 * @param {Array<FieldValue>=} fieldValues: FieldValues to add to the issue.
 * @param {Array<IssueRef>=} blockedOnRefs: IssueRefs for blocked on issues.
 * @param {Array<IssueRef>=} blockingRefs: IssueRefs for blocking issues.
 * @return {Issue}
 */
function makeIssue(
    projectName, summary, description, status, sendEmail, ownerName, ccNames,
    labels, componentNames, fieldValues, blockedOnRefs, blockingRefs) {
  const issue = {
    'summary': summary,
    'status': {'status': status},
    'ccUsers': [],
    'components': [],
    'labels': [],
  };

  if (ownerName) {
    issue['owner'] = {'user': ownerName};
  }

  if (ccNames) {
    ccNames.forEach((ccName) => {
      issue['ccUsers'].push({'user': ccName});
    });
  };

  if (labels) {
    labels.forEach((label) => {
      issue['labels'].push({'label': label});
    });
  };

  if (componentNames) {
    componentNames.forEach((componentName) => {
      issue['components'].push({'component': componentName});
    });
  };

  if (fieldValues) {
    issue['fieldValues'] = fieldValues;
  };

  if (blockedOnRefs) {
    issue['blockedOnIssueRefs'] = blockedOnRefs;
  };

  if (blockingRefs) {
    issue['blockingIssueRefs'] = blockingRefs;
  };

  const message = {
    'parent': projectName,
    'issue': issue,
    'description': description,
    'notifyType': sendEmail ? 'EMAIL': 'NO_NOTIFICATION',
  };
  const url = URL + 'monorail.v3.Issues/MakeIssue';
  return run_(url, message);
}
