/**
 * @license
 * Copyright (C) 2016 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.
 */
import '../../admin/gr-create-change-dialog/gr-create-change-dialog';
import '../../shared/gr-button/gr-button';
import '../../shared/gr-dialog/gr-dialog';
import '../../shared/gr-dropdown/gr-dropdown';
import '../../shared/gr-icons/gr-icons';
import '../../shared/gr-overlay/gr-overlay';
import '../gr-confirm-abandon-dialog/gr-confirm-abandon-dialog';
import '../gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog';
import '../gr-confirm-cherrypick-conflict-dialog/gr-confirm-cherrypick-conflict-dialog';
import '../gr-confirm-move-dialog/gr-confirm-move-dialog';
import '../gr-confirm-rebase-dialog/gr-confirm-rebase-dialog';
import '../gr-confirm-revert-dialog/gr-confirm-revert-dialog';
import '../gr-confirm-revert-submission-dialog/gr-confirm-revert-submission-dialog';
import '../gr-confirm-submit-dialog/gr-confirm-submit-dialog';
import '../../../styles/shared-styles';
import {dom, EventApi} from '@polymer/polymer/lib/legacy/polymer.dom';
import {PolymerElement} from '@polymer/polymer/polymer-element';
import {htmlTemplate} from './gr-change-actions_html';
import {GerritNav} from '../../core/gr-navigation/gr-navigation';
import {getPluginLoader} from '../../shared/gr-js-api-interface/gr-plugin-loader';
import {appContext} from '../../../services/app-context';
import {fetchChangeUpdates, CURRENT} from '../../../utils/patch-set-util';
import {
  changeIsOpen,
  isOwner,
  ListChangesOption,
  listChangesOptionsToHex,
} from '../../../utils/change-util';
import {
  ChangeStatus,
  DraftsAction,
  HttpMethod,
  NotifyType,
} from '../../../constants/constants';
import {EventType as PluginEventType, TargetElement} from '../../../api/plugin';
import {customElement, observe, property} from '@polymer/decorators';
import {
  AccountInfo,
  ActionInfo,
  ActionNameToActionInfoMap,
  BranchName,
  ChangeInfo,
  ChangeViewChangeInfo,
  CherryPickInput,
  CommitId,
  InheritedBooleanInfo,
  isDetailedLabelInfo,
  isQuickLabelInfo,
  LabelInfo,
  NumericChangeId,
  PatchSetNum,
  PropertyType,
  RequestPayload,
  RevertSubmissionInfo,
  ReviewInput,
  ServerInfo,
} from '../../../types/common';
import {GrConfirmAbandonDialog} from '../gr-confirm-abandon-dialog/gr-confirm-abandon-dialog';
import {GrOverlay} from '../../shared/gr-overlay/gr-overlay';
import {GrDialog} from '../../shared/gr-dialog/gr-dialog';
import {GrCreateChangeDialog} from '../../admin/gr-create-change-dialog/gr-create-change-dialog';
import {GrConfirmSubmitDialog} from '../gr-confirm-submit-dialog/gr-confirm-submit-dialog';
import {GrConfirmRevertSubmissionDialog} from '../gr-confirm-revert-submission-dialog/gr-confirm-revert-submission-dialog';
import {
  ConfirmRevertEventDetail,
  GrConfirmRevertDialog,
  RevertType,
} from '../gr-confirm-revert-dialog/gr-confirm-revert-dialog';
import {GrConfirmMoveDialog} from '../gr-confirm-move-dialog/gr-confirm-move-dialog';
import {GrConfirmCherrypickDialog} from '../gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog';
import {GrConfirmCherrypickConflictDialog} from '../gr-confirm-cherrypick-conflict-dialog/gr-confirm-cherrypick-conflict-dialog';
import {
  ConfirmRebaseEventDetail,
  GrConfirmRebaseDialog,
} from '../gr-confirm-rebase-dialog/gr-confirm-rebase-dialog';
import {PolymerDeepPropertyChange} from '@polymer/polymer/interfaces';
import {GrButton} from '../../shared/gr-button/gr-button';
import {
  GrChangeActionsElement,
  UIActionInfo,
} from '../../shared/gr-js-api-interface/gr-change-actions-js-api';
import {fireAlert} from '../../../utils/event-util';
import {
  CODE_REVIEW,
  getApprovalInfo,
  getVotingRange,
} from '../../../utils/label-util';
import {CommentThread} from '../../../utils/comment-util';
import {ShowAlertEventDetail} from '../../../types/events';
import {
  ActionPriority,
  ActionType,
  ChangeActions,
  PrimaryActionKey,
  RevisionActions,
} from '../../../api/change-actions';
import {ErrorCallback} from '../../../api/rest';
import {GrDropdown} from '../../shared/gr-dropdown/gr-dropdown';

const ERR_BRANCH_EMPTY = 'The destination branch can’t be empty.';
const ERR_COMMIT_EMPTY = 'The commit message can’t be empty.';
const ERR_REVISION_ACTIONS = 'Couldn’t load revision actions.';

enum LabelStatus {
  /**
   * This label provides what is necessary for submission.
   */
  OK = 'OK',
  /**
   * This label prevents the change from being submitted.
   */
  REJECT = 'REJECT',
  /**
   * The label may be set, but it's neither necessary for submission
   * nor does it block submission if set.
   */
  MAY = 'MAY',
  /**
   * The label is required for submission, but has not been satisfied.
   */
  NEED = 'NEED',
  /**
   * The label is required for submission, but is impossible to complete.
   * The likely cause is access has not been granted correctly by the
   * project owner or site administrator.
   */
  IMPOSSIBLE = 'IMPOSSIBLE',
  OPTIONAL = 'OPTIONAL',
}

const ActionLoadingLabels: {[actionKey: string]: string} = {
  abandon: 'Abandoning...',
  cherrypick: 'Cherry-picking...',
  delete: 'Deleting...',
  move: 'Moving..',
  rebase: 'Rebasing...',
  restore: 'Restoring...',
  revert: 'Reverting...',
  revert_submission: 'Reverting Submission...',
  submit: 'Submitting...',
};

const ADDITIONAL_ACTION_KEY_PREFIX = '__additionalAction_';

interface QuickApproveUIActionInfo extends UIActionInfo {
  key: string;
  payload?: RequestPayload;
}

const QUICK_APPROVE_ACTION: QuickApproveUIActionInfo = {
  __key: 'review',
  __type: ActionType.CHANGE,
  enabled: true,
  key: 'review',
  label: 'Quick approve',
  method: HttpMethod.POST,
};

function isQuickApproveAction(
  action: UIActionInfo
): action is QuickApproveUIActionInfo {
  return (action as QuickApproveUIActionInfo).key === QUICK_APPROVE_ACTION.key;
}

const DOWNLOAD_ACTION: UIActionInfo = {
  enabled: true,
  label: 'Download patch',
  title: 'Open download dialog',
  __key: 'download',
  __primary: false,
  __type: ActionType.REVISION,
};

const REBASE_EDIT: UIActionInfo = {
  enabled: true,
  label: 'Rebase edit',
  title: 'Rebase change edit',
  __key: 'rebaseEdit',
  __primary: false,
  __type: ActionType.CHANGE,
  method: HttpMethod.POST,
};

const PUBLISH_EDIT: UIActionInfo = {
  enabled: true,
  label: 'Publish edit',
  title: 'Publish change edit',
  __key: 'publishEdit',
  __primary: false,
  __type: ActionType.CHANGE,
  method: HttpMethod.POST,
};

const DELETE_EDIT: UIActionInfo = {
  enabled: true,
  label: 'Delete edit',
  title: 'Delete change edit',
  __key: 'deleteEdit',
  __primary: false,
  __type: ActionType.CHANGE,
  method: HttpMethod.DELETE,
};

const EDIT: UIActionInfo = {
  enabled: true,
  label: 'Edit',
  title: 'Edit this change',
  __key: 'edit',
  __primary: false,
  __type: ActionType.CHANGE,
};

const STOP_EDIT: UIActionInfo = {
  enabled: true,
  label: 'Stop editing',
  title: 'Stop editing this change',
  __key: 'stopEdit',
  __primary: false,
  __type: ActionType.CHANGE,
};

// Set of keys that have icons. As more icons are added to gr-icons.html, this
// set should be expanded.
const ACTIONS_WITH_ICONS = new Set([
  ChangeActions.ABANDON,
  ChangeActions.DELETE_EDIT,
  ChangeActions.EDIT,
  ChangeActions.PUBLISH_EDIT,
  ChangeActions.READY,
  ChangeActions.REBASE_EDIT,
  ChangeActions.RESTORE,
  ChangeActions.REVERT,
  ChangeActions.REVERT_SUBMISSION,
  ChangeActions.STOP_EDIT,
  QUICK_APPROVE_ACTION.key,
  RevisionActions.REBASE,
  RevisionActions.SUBMIT,
]);

const EDIT_ACTIONS: Set<string> = new Set([
  ChangeActions.DELETE_EDIT,
  ChangeActions.EDIT,
  ChangeActions.PUBLISH_EDIT,
  ChangeActions.REBASE_EDIT,
  ChangeActions.STOP_EDIT,
]);

const AWAIT_CHANGE_ATTEMPTS = 5;
const AWAIT_CHANGE_TIMEOUT_MS = 1000;

/* Revert submission is skipped as the normal revert dialog will now show
the user a choice between reverting single change or an entire submission.
Hence, a second button is not needed.
*/
const SKIP_ACTION_KEYS = [ChangeActions.REVERT_SUBMISSION];

const SKIP_ACTION_KEYS_ATTENTION_SET = [
  ChangeActions.REVIEWED,
  ChangeActions.UNREVIEWED,
];

export function assertUIActionInfo(action?: ActionInfo): UIActionInfo {
  // TODO(TS): Remove this function. The gr-change-actions adds properties
  // to existing ActionInfo objects instead of creating a new objects. This
  // function checks, that 'action' has all property required by UIActionInfo.
  // In the future, we should avoid updates of an existing ActionInfos and
  // instead create a new object to make code cleaner. However, at the current
  // state this is unsafe, because other code can expect these properties to be
  // set in ActionInfo.
  if (!action) {
    throw new Error('action is undefined');
  }
  const result = action as UIActionInfo;
  if (result.__key === undefined || result.__type === undefined) {
    throw new Error('action is not an UIActionInfo');
  }
  return result;
}

interface MenuAction {
  name: string;
  id: string;
  action: UIActionInfo;
  tooltip?: string;
}

interface OverflowAction {
  type: ActionType;
  key: string;
  overflow?: boolean;
}

interface ActionPriorityOverride {
  type: ActionType.CHANGE | ActionType.REVISION;
  key: string;
  priority: ActionPriority;
}

interface ChangeActionDialog extends HTMLElement {
  resetFocus?(): void;
  init?(): void;
}

export interface GrChangeActions {
  $: {
    mainContent: Element;
    overlay: GrOverlay;
    confirmRebase: GrConfirmRebaseDialog;
    confirmCherrypick: GrConfirmCherrypickDialog;
    confirmCherrypickConflict: GrConfirmCherrypickConflictDialog;
    confirmMove: GrConfirmMoveDialog;
    confirmRevertDialog: GrConfirmRevertDialog;
    confirmRevertSubmissionDialog: GrConfirmRevertSubmissionDialog;
    confirmAbandonDialog: GrConfirmAbandonDialog;
    confirmSubmitDialog: GrConfirmSubmitDialog;
    createFollowUpDialog: GrDialog;
    createFollowUpChange: GrCreateChangeDialog;
    confirmDeleteDialog: GrDialog;
    confirmDeleteEditDialog: GrDialog;
    moreActions: GrDropdown;
    secondaryActions: HTMLElement;
  };
}

@customElement('gr-change-actions')
export class GrChangeActions extends PolymerElement
  implements GrChangeActionsElement {
  static get template() {
    return htmlTemplate;
  }

  /**
   * Fired when the change should be reloaded.
   *
   * @event reload
   */

  /**
   * Fired when an action is tapped.
   *
   * @event custom-tap - naming pattern: <action key>-tap
   */

  /**
   * Fires to show an alert when a send is attempted on the non-latest patch.
   *
   * @event show-alert
   */

  /**
   * Fires when a change action fails.
   *
   * @event show-error
   */

  // TODO(TS): Ensure that ActionType, ChangeActions and RevisionActions
  // properties are replaced with enums everywhere and remove them from
  // the GrChangeActions class
  ActionType = ActionType;

  ChangeActions = ChangeActions;

  RevisionActions = RevisionActions;

  reporting = appContext.reportingService;

  private readonly jsAPI = appContext.jsApiService;

  @property({type: Object})
  change?: ChangeViewChangeInfo;

  @property({type: Object})
  actions: ActionNameToActionInfoMap = {};

  @property({type: Array})
  primaryActionKeys: PrimaryActionKey[] = [
    ChangeActions.READY,
    RevisionActions.SUBMIT,
  ];

  @property({type: Boolean})
  disableEdit = false;

  @property({type: Boolean})
  _hasKnownChainState = false;

  @property({type: Boolean})
  _hideQuickApproveAction = false;

  @property({type: Object})
  account?: AccountInfo;

  @property({type: String})
  changeNum?: NumericChangeId;

  @property({type: String})
  changeStatus?: ChangeStatus;

  @property({type: String})
  commitNum?: CommitId;

  @property({type: Boolean, observer: '_computeChainState'})
  hasParent?: boolean;

  @property({type: String})
  latestPatchNum?: PatchSetNum;

  @property({type: String})
  commitMessage = '';

  @property({type: Object, notify: true})
  revisionActions: ActionNameToActionInfoMap = {};

  @property({type: Object, computed: '_getSubmitAction(revisionActions)'})
  _revisionSubmitAction?: ActionInfo | null;

  @property({type: Object, computed: '_getRebaseAction(revisionActions)'})
  _revisionRebaseAction?: ActionInfo | null;

  @property({type: String})
  privateByDefault?: InheritedBooleanInfo;

  @property({type: Boolean})
  _loading = true;

  @property({type: String})
  _actionLoadingMessage = '';

  @property({type: Array})
  commentThreads: CommentThread[] = [];

  @property({
    type: Array,
    computed:
      '_computeAllActions(actions.*, revisionActions.*,' +
      'primaryActionKeys.*, _additionalActions.*, change, ' +
      '_config, _actionPriorityOverrides.*)',
  })
  _allActionValues: UIActionInfo[] = []; // _computeAllActions always returns an array

  @property({
    type: Array,
    computed:
      '_computeTopLevelActions(_allActionValues.*, ' +
      '_hiddenActions.*, editMode, _overflowActions.*)',
    observer: '_filterPrimaryActions',
  })
  _topLevelActions?: UIActionInfo[];

  @property({type: Array})
  _topLevelPrimaryActions?: UIActionInfo[];

  @property({type: Array})
  _topLevelSecondaryActions?: UIActionInfo[];

  @property({
    type: Array,
    computed:
      '_computeMenuActions(_allActionValues.*, ' +
      '_hiddenActions.*, _overflowActions.*)',
  })
  _menuActions?: MenuAction[];

  @property({type: Array})
  _overflowActions: OverflowAction[] = [
    {
      type: ActionType.CHANGE,
      key: ChangeActions.WIP,
    },
    {
      type: ActionType.CHANGE,
      key: ChangeActions.DELETE,
    },
    {
      type: ActionType.REVISION,
      key: RevisionActions.CHERRYPICK,
    },
    {
      type: ActionType.CHANGE,
      key: ChangeActions.MOVE,
    },
    {
      type: ActionType.REVISION,
      key: RevisionActions.DOWNLOAD,
    },
    {
      type: ActionType.CHANGE,
      key: ChangeActions.IGNORE,
    },
    {
      type: ActionType.CHANGE,
      key: ChangeActions.UNIGNORE,
    },
    {
      type: ActionType.CHANGE,
      key: ChangeActions.REVIEWED,
    },
    {
      type: ActionType.CHANGE,
      key: ChangeActions.UNREVIEWED,
    },
    {
      type: ActionType.CHANGE,
      key: ChangeActions.PRIVATE,
    },
    {
      type: ActionType.CHANGE,
      key: ChangeActions.PRIVATE_DELETE,
    },
    {
      type: ActionType.CHANGE,
      key: ChangeActions.FOLLOW_UP,
    },
  ];

  @property({type: Array})
  _actionPriorityOverrides: ActionPriorityOverride[] = [];

  @property({type: Array})
  _additionalActions: UIActionInfo[] = [];

  @property({type: Array})
  _hiddenActions: string[] = [];

  @property({type: Array})
  _disabledMenuActions: string[] = [];

  @property({type: Boolean})
  editPatchsetLoaded = false;

  @property({type: Boolean})
  editMode = false;

  @property({type: Boolean})
  editBasedOnCurrentPatchSet = true;

  @property({type: Object})
  _config?: ServerInfo;

  private readonly restApiService = appContext.restApiService;

  constructor() {
    super();
    this.addEventListener('fullscreen-overlay-opened', () =>
      this._handleHideBackgroundContent()
    );
    this.addEventListener('fullscreen-overlay-closed', () =>
      this._handleShowBackgroundContent()
    );
  }

  /** @override */
  ready() {
    super.ready();
    this.jsAPI.addElement(TargetElement.CHANGE_ACTIONS, this);
    this.restApiService.getConfig().then(config => {
      this._config = config;
    });
    this._handleLoadingComplete();
  }

  _getSubmitAction(revisionActions: ActionNameToActionInfoMap) {
    return this._getRevisionAction(revisionActions, 'submit');
  }

  _getRebaseAction(revisionActions: ActionNameToActionInfoMap) {
    return this._getRevisionAction(revisionActions, 'rebase');
  }

  _getRevisionAction(
    revisionActions: ActionNameToActionInfoMap,
    actionName: string
  ) {
    if (!revisionActions) {
      return undefined;
    }
    if (revisionActions[actionName] === undefined) {
      // Return null to fire an event when reveisionActions was loaded
      // but doesn't contain actionName. undefined doesn't fire an event
      return null;
    }
    return revisionActions[actionName];
  }

  reload() {
    if (!this.changeNum || !this.latestPatchNum || !this.change) {
      return Promise.resolve();
    }
    const change = this.change;

    this._loading = true;
    return this.restApiService
      .getChangeRevisionActions(this.changeNum, this.latestPatchNum)
      .then(revisionActions => {
        if (!revisionActions) {
          return;
        }

        this.revisionActions = revisionActions;
        this._sendShowRevisionActions({
          change,
          revisionActions,
        });
        this._handleLoadingComplete();
      })
      .catch(err => {
        fireAlert(this, ERR_REVISION_ACTIONS);
        this._loading = false;
        throw err;
      });
  }

  _handleLoadingComplete() {
    getPluginLoader()
      .awaitPluginsLoaded()
      .then(() => (this._loading = false));
  }

  _sendShowRevisionActions(detail: {
    change: ChangeInfo;
    revisionActions: ActionNameToActionInfoMap;
  }) {
    this.jsAPI.handleEvent(PluginEventType.SHOW_REVISION_ACTIONS, detail);
  }

  @observe('change')
  _changeChanged() {
    this.reload();
  }

  addActionButton(type: ActionType, label: string) {
    if (type !== ActionType.CHANGE && type !== ActionType.REVISION) {
      throw Error(`Invalid action type: ${type}`);
    }
    const action: UIActionInfo = {
      enabled: true,
      label,
      __type: type,
      __key:
        ADDITIONAL_ACTION_KEY_PREFIX + Math.random().toString(36).substr(2),
    };
    this.push('_additionalActions', action);
    return action.__key;
  }

  removeActionButton(key: string) {
    const idx = this._indexOfActionButtonWithKey(key);
    if (idx === -1) {
      return;
    }
    this.splice('_additionalActions', idx, 1);
  }

  setActionButtonProp<T extends keyof UIActionInfo>(
    key: string,
    prop: T,
    value: UIActionInfo[T]
  ) {
    this.set(
      ['_additionalActions', this._indexOfActionButtonWithKey(key), prop],
      value
    );
  }

  setActionOverflow(type: ActionType, key: string, overflow: boolean) {
    if (type !== ActionType.CHANGE && type !== ActionType.REVISION) {
      throw Error(`Invalid action type given: ${type}`);
    }
    const index = this._getActionOverflowIndex(type, key);
    const action: OverflowAction = {
      type,
      key,
      overflow,
    };
    if (!overflow && index !== -1) {
      this.splice('_overflowActions', index, 1);
    } else if (overflow) {
      this.push('_overflowActions', action);
    }
  }

  setActionPriority(
    type: ActionType.CHANGE | ActionType.REVISION,
    key: string,
    priority: ActionPriority
  ) {
    if (type !== ActionType.CHANGE && type !== ActionType.REVISION) {
      throw Error(`Invalid action type given: ${type}`);
    }
    const index = this._actionPriorityOverrides.findIndex(
      action => action.type === type && action.key === key
    );
    const action: ActionPriorityOverride = {
      type,
      key,
      priority,
    };
    if (index !== -1) {
      this.set('_actionPriorityOverrides', index, action);
    } else {
      this.push('_actionPriorityOverrides', action);
    }
  }

  setActionHidden(
    type: ActionType.CHANGE | ActionType.REVISION,
    key: string,
    hidden: boolean
  ) {
    if (type !== ActionType.CHANGE && type !== ActionType.REVISION) {
      throw Error(`Invalid action type given: ${type}`);
    }

    const idx = this._hiddenActions.indexOf(key);
    if (hidden && idx === -1) {
      this.push('_hiddenActions', key);
    } else if (!hidden && idx !== -1) {
      this.splice('_hiddenActions', idx, 1);
    }
  }

  getActionDetails(actionName: string) {
    if (this.revisionActions[actionName]) {
      return this.revisionActions[actionName];
    } else if (this.actions[actionName]) {
      return this.actions[actionName];
    } else {
      return undefined;
    }
  }

  _indexOfActionButtonWithKey(key: string) {
    for (let i = 0; i < this._additionalActions.length; i++) {
      if (this._additionalActions[i].__key === key) {
        return i;
      }
    }
    return -1;
  }

  _shouldHideActions(
    actions?: PolymerDeepPropertyChange<UIActionInfo[], UIActionInfo[]>,
    loading?: boolean
  ) {
    return loading || !actions || !actions.base || !actions.base.length;
  }

  _keyCount(
    changeRecord?: PolymerDeepPropertyChange<
      ActionNameToActionInfoMap,
      ActionNameToActionInfoMap
    >
  ) {
    return Object.keys(changeRecord?.base || {}).length;
  }

  @observe('actions.*', 'revisionActions.*', '_additionalActions.*')
  _actionsChanged(
    actionsChangeRecord?: PolymerDeepPropertyChange<
      ActionNameToActionInfoMap,
      ActionNameToActionInfoMap
    >,
    revisionActionsChangeRecord?: PolymerDeepPropertyChange<
      ActionNameToActionInfoMap,
      ActionNameToActionInfoMap
    >,
    additionalActionsChangeRecord?: PolymerDeepPropertyChange<
      UIActionInfo[],
      UIActionInfo[]
    >
  ) {
    // Polymer 2: check for undefined
    if (
      actionsChangeRecord === undefined ||
      revisionActionsChangeRecord === undefined ||
      additionalActionsChangeRecord === undefined
    ) {
      return;
    }

    const additionalActions =
      (additionalActionsChangeRecord && additionalActionsChangeRecord.base) ||
      [];
    this.hidden =
      this._keyCount(actionsChangeRecord) === 0 &&
      this._keyCount(revisionActionsChangeRecord) === 0 &&
      additionalActions.length === 0;
    this._actionLoadingMessage = '';
    this._actionLoadingMessage = '';
    this._disabledMenuActions = [];

    const revisionActions = revisionActionsChangeRecord.base || {};
    if (Object.keys(revisionActions).length !== 0) {
      if (!revisionActions.download) {
        this.set('revisionActions.download', DOWNLOAD_ACTION);
      }
    }
  }

  _deleteAndNotify(actionName: string) {
    if (this.actions && this.actions[actionName]) {
      delete this.actions[actionName];
      // We assign a fake value of 'false' to support Polymer 2
      // see https://github.com/Polymer/polymer/issues/2631
      this.notifyPath('actions.' + actionName, false);
    }
  }

  @observe(
    'editMode',
    'editPatchsetLoaded',
    'editBasedOnCurrentPatchSet',
    'disableEdit',
    'actions.*',
    'change.*'
  )
  _editStatusChanged(
    editMode: boolean,
    editPatchsetLoaded: boolean,
    editBasedOnCurrentPatchSet: boolean,
    disableEdit: boolean,
    actionsChangeRecord?: PolymerDeepPropertyChange<
      ActionNameToActionInfoMap,
      ActionNameToActionInfoMap
    >,
    changeChangeRecord?: PolymerDeepPropertyChange<ChangeInfo, ChangeInfo>
  ) {
    if (actionsChangeRecord === undefined || changeChangeRecord === undefined) {
      return;
    }
    if (disableEdit) {
      this._deleteAndNotify('publishEdit');
      this._deleteAndNotify('rebaseEdit');
      this._deleteAndNotify('deleteEdit');
      this._deleteAndNotify('stopEdit');
      this._deleteAndNotify('edit');
      return;
    }
    const actions = actionsChangeRecord.base;
    const change = changeChangeRecord.base;
    if (actions && editPatchsetLoaded) {
      // Only show actions that mutate an edit if an actual edit patch set
      // is loaded.
      if (changeIsOpen(change)) {
        if (editBasedOnCurrentPatchSet) {
          if (!actions.publishEdit) {
            this.set('actions.publishEdit', PUBLISH_EDIT);
          }
          this._deleteAndNotify('rebaseEdit');
        } else {
          if (!actions.rebaseEdit) {
            this.set('actions.rebaseEdit', REBASE_EDIT);
          }
          this._deleteAndNotify('publishEdit');
        }
      }
      if (!actions.deleteEdit) {
        this.set('actions.deleteEdit', DELETE_EDIT);
      }
    } else {
      this._deleteAndNotify('publishEdit');
      this._deleteAndNotify('rebaseEdit');
      this._deleteAndNotify('deleteEdit');
    }

    if (actions && changeIsOpen(change)) {
      // Only show edit button if there is no edit patchset loaded and the
      // file list is not in edit mode.
      if (editPatchsetLoaded || editMode) {
        this._deleteAndNotify('edit');
      } else {
        if (!actions.edit) {
          this.set('actions.edit', EDIT);
        }
      }
      // Only show STOP_EDIT if edit mode is enabled, but no edit patch set
      // is loaded.
      if (editMode && !editPatchsetLoaded) {
        if (!actions.stopEdit) {
          this.set('actions.stopEdit', STOP_EDIT);
          fireAlert(this, 'Change is in edit mode');
        }
      } else {
        this._deleteAndNotify('stopEdit');
      }
    } else {
      // Remove edit button.
      this._deleteAndNotify('edit');
    }
  }

  _getValuesFor<T>(obj: {[key: string]: T}): T[] {
    return Object.keys(obj).map(key => obj[key]);
  }

  _getLabelStatus(label: LabelInfo): LabelStatus {
    if (isQuickLabelInfo(label)) {
      if (label.approved) {
        return LabelStatus.OK;
      } else if (label.rejected) {
        return LabelStatus.REJECT;
      }
    }
    if (label.optional) {
      return LabelStatus.OPTIONAL;
    } else {
      return LabelStatus.NEED;
    }
  }

  /**
   * Get highest score for last missing permitted label for current change.
   * Returns null if no labels permitted or more than one label missing.
   */
  _getTopMissingApproval() {
    if (!this.change || !this.change.labels || !this.change.permitted_labels) {
      return null;
    }
    if (this.change && this.change.status === ChangeStatus.MERGED) {
      return null;
    }
    let result;
    for (const [label, labelInfo] of Object.entries(this.change.labels)) {
      if (!(label in this.change.permitted_labels)) {
        continue;
      }
      if (this.change.permitted_labels[label].length === 0) {
        continue;
      }
      const status = this._getLabelStatus(labelInfo);
      if (status === LabelStatus.NEED) {
        if (result) {
          // More than one label is missing, so check if Code Review can be
          // given
          result = null;
          break;
        }
        result = label;
      } else if (
        status === LabelStatus.REJECT ||
        status === LabelStatus.IMPOSSIBLE
      ) {
        return null;
      }
    }
    // Allow the user to use quick approve to vote the max score on code review
    // even if it is already granted by someone else. Does not apply if the
    // user owns the change or has already granted the max score themselves.
    const codeReviewLabel = this.change.labels[CODE_REVIEW];
    const codeReviewPermittedValues = this.change.permitted_labels[CODE_REVIEW];
    if (
      !result &&
      codeReviewLabel &&
      codeReviewPermittedValues &&
      this.account?._account_id &&
      isDetailedLabelInfo(codeReviewLabel) &&
      this._getLabelStatus(codeReviewLabel) === LabelStatus.OK &&
      !isOwner(this.change, this.account) &&
      getApprovalInfo(codeReviewLabel, this.account)?.value !==
        getVotingRange(codeReviewLabel)?.max
    ) {
      result = CODE_REVIEW;
    }

    if (result) {
      const labelInfo = this.change.labels[result];
      if (!isDetailedLabelInfo(labelInfo)) {
        return null;
      }
      const permittedValues = this.change.permitted_labels[result];
      const usersMaxPermittedScore =
        permittedValues[permittedValues.length - 1];
      const maxScoreForLabel = getVotingRange(labelInfo)?.max;
      if (Number(usersMaxPermittedScore) === maxScoreForLabel) {
        // Allow quick approve only for maximal score.
        return {
          label: result,
          score: usersMaxPermittedScore,
        };
      }
    }
    return null;
  }

  hideQuickApproveAction() {
    if (!this._topLevelSecondaryActions) {
      throw new Error('_topLevelSecondaryActions must be set');
    }
    this._topLevelSecondaryActions = this._topLevelSecondaryActions.filter(
      sa => !isQuickApproveAction(sa)
    );
    this._hideQuickApproveAction = true;
  }

  _getQuickApproveAction(): QuickApproveUIActionInfo | null {
    if (this._hideQuickApproveAction) {
      return null;
    }
    const approval = this._getTopMissingApproval();
    if (!approval) {
      return null;
    }
    const action = {...QUICK_APPROVE_ACTION};
    action.label = approval.label + approval.score;

    const score = Number(approval.score);
    if (isNaN(score)) {
      return null;
    }

    const review: ReviewInput = {
      drafts: DraftsAction.PUBLISH_ALL_REVISIONS,
      labels: {
        [approval.label]: score,
      },
    };
    action.payload = review;
    return action;
  }

  _getActionValues(
    actionsChangeRecord: PolymerDeepPropertyChange<
      ActionNameToActionInfoMap,
      ActionNameToActionInfoMap
    >,
    primariesChangeRecord: PolymerDeepPropertyChange<
      PrimaryActionKey[],
      PrimaryActionKey[]
    >,
    additionalActionsChangeRecord: PolymerDeepPropertyChange<
      UIActionInfo[],
      UIActionInfo[]
    >,
    type: ActionType
  ): UIActionInfo[] {
    if (!actionsChangeRecord || !primariesChangeRecord) {
      return [];
    }

    const actions = actionsChangeRecord.base || {};
    const primaryActionKeys = primariesChangeRecord.base || [];
    const result: UIActionInfo[] = [];
    const values: Array<ChangeActions | RevisionActions> =
      type === ActionType.CHANGE
        ? this._getValuesFor(ChangeActions)
        : this._getValuesFor(RevisionActions);

    const pluginActions: UIActionInfo[] = [];
    Object.keys(actions).forEach(a => {
      const action: UIActionInfo = actions[a] as UIActionInfo;
      action.__key = a;
      action.__type = type;
      action.__primary = primaryActionKeys.includes(a as PrimaryActionKey);
      // Plugin actions always contain ~ in the key.
      if (a.indexOf('~') !== -1) {
        this._populateActionUrl(action);
        pluginActions.push(action);
        // Add server-side provided plugin actions to overflow menu.
        this._overflowActions.push({
          type,
          key: a,
        });
        return;
      } else if (!values.includes(a as PrimaryActionKey)) {
        return;
      }
      action.label = this._getActionLabel(action);

      // Triggers a re-render by ensuring object inequality.
      result.push({...action});
    });

    let additionalActions =
      (additionalActionsChangeRecord && additionalActionsChangeRecord.base) ||
      [];
    additionalActions = additionalActions
      .filter(a => a.__type === type)
      .map(a => {
        a.__primary = primaryActionKeys.includes(a.__key as PrimaryActionKey);
        // Triggers a re-render by ensuring object inequality.
        return {...a};
      });
    return result.concat(additionalActions).concat(pluginActions);
  }

  _populateActionUrl(action: UIActionInfo) {
    const patchNum =
      action.__type === ActionType.REVISION ? this.latestPatchNum : undefined;
    if (!this.changeNum) {
      return;
    }
    this.restApiService
      .getChangeActionURL(this.changeNum, patchNum, '/' + action.__key)
      .then(url => (action.__url = url));
  }

  /**
   * Given a change action, return a display label that uses the appropriate
   * casing or includes explanatory details.
   */
  _getActionLabel(action: UIActionInfo) {
    if (action.label === 'Delete') {
      // This label is common within change and revision actions. Make it more
      // explicit to the user.
      return 'Delete change';
    } else if (action.label === 'WIP') {
      return 'Mark as work in progress';
    }
    // Otherwise, just map the name to sentence case.
    return this._toSentenceCase(action.label);
  }

  /**
   * Capitalize the first letter and lowecase all others.
   */
  _toSentenceCase(s: string) {
    if (!s.length) {
      return '';
    }
    return s[0].toUpperCase() + s.slice(1).toLowerCase();
  }

  _computeLoadingLabel(action: string) {
    return ActionLoadingLabels[action] || 'Working...';
  }

  _canSubmitChange() {
    if (!this.change) {
      return false;
    }
    return this.jsAPI.canSubmitChange(
      this.change,
      this._getRevision(this.change, this.latestPatchNum)
    );
  }

  _getRevision(change: ChangeViewChangeInfo, patchNum?: PatchSetNum) {
    for (const rev of Object.values(change.revisions)) {
      if (rev._number === patchNum) {
        return rev;
      }
    }
    return null;
  }

  showRevertDialog() {
    const change = this.change;
    if (!change) return;
    // The search is still broken if there is a " in the topic.
    const query = `submissionid: "${change.submission_id}"`;
    /* A chromium plugin expects that the modifyRevertMsg hook will only
    be called after the revert button is pressed, hence we populate the
    revert dialog after revert button is pressed. */
    this.restApiService.getChanges(0, query).then(changes => {
      if (!changes) {
        this.reporting.error(new Error('changes is undefined'));
        return;
      }
      this.$.confirmRevertDialog.populate(change, this.commitMessage, changes);
      this._showActionDialog(this.$.confirmRevertDialog);
    });
  }

  showRevertSubmissionDialog() {
    const change = this.change;
    if (!change) return;
    const query = `submissionid:${change.submission_id}`;
    this.restApiService.getChanges(0, query).then(changes => {
      if (!changes) {
        this.reporting.error(new Error('changes is undefined'));
        return;
      }
      this.$.confirmRevertSubmissionDialog._populateRevertSubmissionMessage(
        change,
        changes
      );
      this._showActionDialog(this.$.confirmRevertSubmissionDialog);
    });
  }

  _handleActionTap(e: MouseEvent) {
    e.preventDefault();
    let el = (dom(e) as EventApi).localTarget as Element;
    while (el.tagName.toLowerCase() !== 'gr-button') {
      if (!el.parentElement) {
        return;
      }
      el = el.parentElement;
    }

    const key = el.getAttribute('data-action-key');
    if (!key) {
      throw new Error("Button doesn't have data-action-key attribute");
    }
    if (
      key.startsWith(ADDITIONAL_ACTION_KEY_PREFIX) ||
      key.indexOf('~') !== -1
    ) {
      this.dispatchEvent(
        new CustomEvent(`${key}-tap`, {
          detail: {node: el},
          composed: true,
          bubbles: true,
        })
      );
      return;
    }
    const type = el.getAttribute('data-action-type') as ActionType;
    this._handleAction(type, key);
  }

  _handleOverflowItemTap(e: CustomEvent<MenuAction>) {
    e.preventDefault();
    const el = (dom(e) as EventApi).localTarget as Element;
    const key = e.detail.action.__key;
    if (
      key.startsWith(ADDITIONAL_ACTION_KEY_PREFIX) ||
      key.indexOf('~') !== -1
    ) {
      this.dispatchEvent(
        new CustomEvent(`${key}-tap`, {
          detail: {node: el},
          composed: true,
          bubbles: true,
        })
      );
      return;
    }
    this._handleAction(e.detail.action.__type, e.detail.action.__key);
  }

  _handleAction(type: ActionType, key: string) {
    this.reporting.reportInteraction(`${type}-${key}`);
    switch (type) {
      case ActionType.REVISION:
        this._handleRevisionAction(key);
        break;
      case ActionType.CHANGE:
        this._handleChangeAction(key);
        break;
      default:
        this._fireAction(
          this._prependSlash(key),
          assertUIActionInfo(this.actions[key]),
          false
        );
    }
  }

  _handleChangeAction(key: string) {
    switch (key) {
      case ChangeActions.REVERT:
        this.showRevertDialog();
        break;
      case ChangeActions.REVERT_SUBMISSION:
        this.showRevertSubmissionDialog();
        break;
      case ChangeActions.ABANDON:
        this._showActionDialog(this.$.confirmAbandonDialog);
        break;
      case QUICK_APPROVE_ACTION.key: {
        const action = this._allActionValues.find(isQuickApproveAction);
        if (!action) {
          return;
        }
        this._fireAction(this._prependSlash(key), action, true, action.payload);
        break;
      }
      case ChangeActions.EDIT:
        this._handleEditTap();
        break;
      case ChangeActions.STOP_EDIT:
        this._handleStopEditTap();
        break;
      case ChangeActions.DELETE:
        this._handleDeleteTap();
        break;
      case ChangeActions.DELETE_EDIT:
        this._handleDeleteEditTap();
        break;
      case ChangeActions.FOLLOW_UP:
        this._handleFollowUpTap();
        break;
      case ChangeActions.WIP:
        this._handleWipTap();
        break;
      case ChangeActions.MOVE:
        this._handleMoveTap();
        break;
      case ChangeActions.PUBLISH_EDIT:
        this._handlePublishEditTap();
        break;
      case ChangeActions.REBASE_EDIT:
        this._handleRebaseEditTap();
        break;
      default:
        this._fireAction(
          this._prependSlash(key),
          assertUIActionInfo(this.actions[key]),
          false
        );
    }
  }

  _handleRevisionAction(key: string) {
    switch (key) {
      case RevisionActions.REBASE:
        this._showActionDialog(this.$.confirmRebase);
        this.$.confirmRebase.fetchRecentChanges();
        break;
      case RevisionActions.CHERRYPICK:
        this._handleCherrypickTap();
        break;
      case RevisionActions.DOWNLOAD:
        this._handleDownloadTap();
        break;
      case RevisionActions.SUBMIT:
        if (!this._canSubmitChange()) {
          return;
        }
        this._showActionDialog(this.$.confirmSubmitDialog);
        break;
      default:
        this._fireAction(
          this._prependSlash(key),
          assertUIActionInfo(this.revisionActions[key]),
          true
        );
    }
  }

  _prependSlash(key: string) {
    return key === '/' ? key : `/${key}`;
  }

  /**
   * _hasKnownChainState set to true true if hasParent is defined (can be
   * either true or false). set to false otherwise.
   */
  _computeChainState() {
    this._hasKnownChainState = true;
  }

  _calculateDisabled(action: UIActionInfo, hasKnownChainState: boolean) {
    if (action.__key === 'rebase') {
      // Rebase button is only disabled when change has no parent(s).
      return hasKnownChainState === false;
    }
    return !action.enabled;
  }

  _handleConfirmDialogCancel() {
    this._hideAllDialogs();
  }

  _hideAllDialogs() {
    const dialogEls = this.root!.querySelectorAll('.confirmDialog');
    for (const dialogEl of dialogEls) {
      (dialogEl as HTMLElement).hidden = true;
    }
    this.$.overlay.close();
  }

  _handleRebaseConfirm(e: CustomEvent<ConfirmRebaseEventDetail>) {
    const el = this.$.confirmRebase;
    const payload = {base: e.detail.base};
    this.$.overlay.close();
    el.hidden = true;
    this._fireAction(
      '/rebase',
      assertUIActionInfo(this.revisionActions.rebase),
      true,
      payload
    );
  }

  _handleCherrypickConfirm() {
    this._handleCherryPickRestApi(false);
  }

  _handleCherrypickConflictConfirm() {
    this._handleCherryPickRestApi(true);
  }

  _handleCherryPickRestApi(conflicts: boolean) {
    const el = this.$.confirmCherrypick;
    if (!el.branch) {
      fireAlert(this, ERR_BRANCH_EMPTY);
      return;
    }
    if (!el.message) {
      fireAlert(this, ERR_COMMIT_EMPTY);
      return;
    }
    this.$.overlay.close();
    el.hidden = true;
    this._fireAction(
      '/cherrypick',
      assertUIActionInfo(this.revisionActions.cherrypick),
      true,
      {
        destination: el.branch,
        base: el.baseCommit ? el.baseCommit : null,
        message: el.message,
        allow_conflicts: conflicts,
      }
    );
  }

  _handleMoveConfirm() {
    const el = this.$.confirmMove;
    if (!el.branch) {
      fireAlert(this, ERR_BRANCH_EMPTY);
      return;
    }
    this.$.overlay.close();
    el.hidden = true;
    this._fireAction('/move', assertUIActionInfo(this.actions.move), false, {
      destination_branch: el.branch,
      message: el.message,
    });
  }

  _handleRevertDialogConfirm(e: CustomEvent<ConfirmRevertEventDetail>) {
    const revertType = e.detail.revertType;
    const message = e.detail.message;
    const el = this.$.confirmRevertDialog;
    this.$.overlay.close();
    el.hidden = true;
    switch (revertType) {
      case RevertType.REVERT_SINGLE_CHANGE:
        this._fireAction(
          '/revert',
          assertUIActionInfo(this.actions.revert),
          false,
          {message}
        );
        break;
      case RevertType.REVERT_SUBMISSION:
        this._fireAction(
          '/revert_submission',
          assertUIActionInfo(this.actions.revert_submission),
          false,
          {message}
        );
        break;
      default:
        this.reporting.error(new Error('invalid revert type'));
    }
  }

  _handleRevertSubmissionDialogConfirm() {
    const el = this.$.confirmRevertSubmissionDialog;
    this.$.overlay.close();
    el.hidden = true;
    this._fireAction(
      '/revert_submission',
      assertUIActionInfo(this.actions.revert_submission),
      false,
      {message: el.message}
    );
  }

  _handleAbandonDialogConfirm() {
    const el = this.$.confirmAbandonDialog;
    this.$.overlay.close();
    el.hidden = true;
    this._fireAction(
      '/abandon',
      assertUIActionInfo(this.actions.abandon),
      false,
      {
        message: el.message,
      }
    );
  }

  _handleCreateFollowUpChange() {
    this.$.createFollowUpChange.handleCreateChange();
    this._handleCloseCreateFollowUpChange();
  }

  _handleCloseCreateFollowUpChange() {
    this.$.overlay.close();
  }

  _handleDeleteConfirm() {
    this._fireAction(
      '/',
      assertUIActionInfo(this.actions[ChangeActions.DELETE]),
      false
    );
  }

  _handleDeleteEditConfirm() {
    this._hideAllDialogs();

    this._fireAction(
      '/edit',
      assertUIActionInfo(this.actions.deleteEdit),
      false
    );
  }

  _handleSubmitConfirm() {
    if (!this._canSubmitChange()) {
      return;
    }
    this._hideAllDialogs();
    this._fireAction(
      '/submit',
      assertUIActionInfo(this.revisionActions.submit),
      true
    );
  }

  _getActionOverflowIndex(type: string, key: string) {
    return this._overflowActions.findIndex(
      action => action.type === type && action.key === key
    );
  }

  _setLoadingOnButtonWithKey(type: string, key: string) {
    this._actionLoadingMessage = this._computeLoadingLabel(key);
    let buttonKey = key;
    // TODO(dhruvsri): clean this up later
    // If key is revert-submission, then button key should be 'revert'
    if (buttonKey === ChangeActions.REVERT_SUBMISSION) {
      // Revert submission button no longer exists
      buttonKey = ChangeActions.REVERT;
    }

    // If the action appears in the overflow menu.
    if (this._getActionOverflowIndex(type, buttonKey) !== -1) {
      this.push(
        '_disabledMenuActions',
        buttonKey === '/' ? 'delete' : buttonKey
      );
      return () => {
        this._actionLoadingMessage = '';
        this._disabledMenuActions = [];
      };
    }

    // Otherwise it's a top-level action.
    const buttonEl = this.shadowRoot!.querySelector(
      `[data-action-key="${buttonKey}"]`
    ) as GrButton;
    if (!buttonEl) {
      throw new Error(`Can't find button by data-action-key '${buttonKey}'`);
    }
    buttonEl.setAttribute('loading', 'true');
    buttonEl.disabled = true;
    return () => {
      this._actionLoadingMessage = '';
      buttonEl.removeAttribute('loading');
      buttonEl.disabled = false;
    };
  }

  _fireAction(
    endpoint: string,
    action: UIActionInfo,
    revAction: boolean,
    payload?: RequestPayload
  ) {
    const cleanupFn = this._setLoadingOnButtonWithKey(
      action.__type,
      action.__key
    );

    this._send(
      action.method,
      payload,
      endpoint,
      revAction,
      cleanupFn,
      action
    ).then(res => this._handleResponse(action, res));
  }

  _showActionDialog(dialog: ChangeActionDialog) {
    this._hideAllDialogs();
    if (dialog.init) dialog.init();
    dialog.hidden = false;
    this.$.overlay.open().then(() => {
      if (dialog.resetFocus) {
        dialog.resetFocus();
      }
    });
  }

  // TODO(rmistry): Redo this after
  // https://bugs.chromium.org/p/gerrit/issues/detail?id=4671 is resolved.
  _setReviewOnRevert(newChangeId: NumericChangeId) {
    const review = this.jsAPI.getReviewPostRevert(this.change);
    if (!review) {
      return Promise.resolve(undefined);
    }
    return this.restApiService.saveChangeReview(newChangeId, CURRENT, review);
  }

  _handleResponse(action: UIActionInfo, response?: Response) {
    if (!response) {
      return;
    }
    return this.restApiService.getResponseObject(response).then(obj => {
      switch (action.__key) {
        case ChangeActions.REVERT: {
          const revertChangeInfo: ChangeInfo = (obj as unknown) as ChangeInfo;
          this._waitForChangeReachable(revertChangeInfo._number)
            .then(() => this._setReviewOnRevert(revertChangeInfo._number))
            .then(() => {
              GerritNav.navigateToChange(revertChangeInfo);
            });
          break;
        }
        case RevisionActions.CHERRYPICK: {
          const cherrypickChangeInfo: ChangeInfo = (obj as unknown) as ChangeInfo;
          this._waitForChangeReachable(cherrypickChangeInfo._number).then(
            () => {
              GerritNav.navigateToChange(cherrypickChangeInfo);
            }
          );
          break;
        }
        case ChangeActions.DELETE:
          if (action.__type === ActionType.CHANGE) {
            GerritNav.navigateToRelativeUrl(GerritNav.getUrlForRoot());
          }
          break;
        case ChangeActions.WIP:
        case ChangeActions.DELETE_EDIT:
        case ChangeActions.PUBLISH_EDIT:
        case ChangeActions.REBASE_EDIT:
        case ChangeActions.REBASE:
        case ChangeActions.SUBMIT:
          this.dispatchEvent(
            new CustomEvent('reload', {
              detail: {clearPatchset: true},
              bubbles: false,
              composed: true,
            })
          );
          break;
        case ChangeActions.REVERT_SUBMISSION: {
          const revertSubmistionInfo = (obj as unknown) as RevertSubmissionInfo;
          if (
            !revertSubmistionInfo.revert_changes ||
            !revertSubmistionInfo.revert_changes.length
          )
            return;
          /* If there is only 1 change then gerrit will automatically
             redirect to that change */
          GerritNav.navigateToSearchQuery(
            `topic: ${revertSubmistionInfo.revert_changes[0].topic}`
          );
          break;
        }
        default:
          this.dispatchEvent(
            new CustomEvent('reload', {
              detail: {action: action.__key, clearPatchset: true},
              bubbles: false,
              composed: true,
            })
          );
          break;
      }
    });
  }

  _handleShowRevertSubmissionChangesConfirm() {
    this._hideAllDialogs();
  }

  _handleResponseError(
    action: UIActionInfo,
    response: Response | undefined | null,
    body?: RequestPayload
  ) {
    if (!response) {
      return Promise.resolve(() => {
        this.dispatchEvent(
          new CustomEvent('show-error', {
            detail: {message: `Could not perform action '${action.__key}'`},
            composed: true,
            bubbles: true,
          })
        );
      });
    }
    if (action && action.__key === RevisionActions.CHERRYPICK) {
      if (
        response.status === 409 &&
        body &&
        !(body as CherryPickInput).allow_conflicts
      ) {
        return this._showActionDialog(this.$.confirmCherrypickConflict);
      }
    }
    return response.text().then(errText => {
      this.dispatchEvent(
        new CustomEvent('show-error', {
          detail: {message: `Could not perform action: ${errText}`},
          composed: true,
          bubbles: true,
        })
      );
      if (!errText.startsWith('Change is already up to date')) {
        throw Error(errText);
      }
    });
  }

  _send(
    method: HttpMethod | undefined,
    payload: RequestPayload | undefined,
    actionEndpoint: string,
    revisionAction: boolean,
    cleanupFn: () => void,
    action: UIActionInfo
  ): Promise<Response | undefined> {
    const handleError: ErrorCallback = response => {
      cleanupFn.call(this);
      this._handleResponseError(action, response, payload);
    };
    const change = this.change;
    const changeNum = this.changeNum;
    if (!change || !changeNum) {
      return Promise.reject(
        new Error('Properties change and changeNum must be set.')
      );
    }
    return fetchChangeUpdates(change, this.restApiService).then(result => {
      if (!result.isLatest) {
        this.dispatchEvent(
          new CustomEvent<ShowAlertEventDetail>('show-alert', {
            detail: {
              message:
                'Cannot set label: a newer patch has been ' +
                'uploaded to this change.',
              action: 'Reload',
              callback: () => {
                this.dispatchEvent(
                  new CustomEvent('reload', {
                    detail: {clearPatchset: true},
                    bubbles: false,
                    composed: true,
                  })
                );
              },
            },
            composed: true,
            bubbles: true,
          })
        );

        // Because this is not a network error, call the cleanup function
        // but not the error handler.
        cleanupFn();

        return Promise.resolve(undefined);
      }
      const patchNum = revisionAction ? this.latestPatchNum : undefined;
      return this.restApiService
        .executeChangeAction(
          changeNum,
          method,
          actionEndpoint,
          patchNum,
          payload,
          handleError
        )
        .then(response => {
          cleanupFn.call(this);
          return response;
        });
    });
  }

  _handleAbandonTap() {
    this._showActionDialog(this.$.confirmAbandonDialog);
  }

  _handleCherrypickTap() {
    if (!this.change) {
      throw new Error('The change property must be set');
    }
    this.$.confirmCherrypick.branch = '' as BranchName;
    const query = `topic: "${this.change.topic}"`;
    const options = listChangesOptionsToHex(
      ListChangesOption.MESSAGES,
      ListChangesOption.ALL_REVISIONS
    );
    this.restApiService
      .getChanges(0, query, undefined, options)
      .then(changes => {
        if (!changes) {
          this.reporting.error(new Error('getChanges returns undefined'));
          return;
        }
        this.$.confirmCherrypick.updateChanges(changes);
        this._showActionDialog(this.$.confirmCherrypick);
      });
  }

  _handleMoveTap() {
    this.$.confirmMove.branch = '' as BranchName;
    this.$.confirmMove.message = '';
    this._showActionDialog(this.$.confirmMove);
  }

  _handleDownloadTap() {
    this.dispatchEvent(
      new CustomEvent('download-tap', {
        composed: true,
        bubbles: false,
      })
    );
  }

  _handleDeleteTap() {
    this._showActionDialog(this.$.confirmDeleteDialog);
  }

  _handleDeleteEditTap() {
    this._showActionDialog(this.$.confirmDeleteEditDialog);
  }

  _handleFollowUpTap() {
    this._showActionDialog(this.$.createFollowUpDialog);
  }

  _handleWipTap() {
    if (!this.actions.wip) {
      return;
    }
    this._fireAction('/wip', assertUIActionInfo(this.actions.wip), false);
  }

  _handlePublishEditTap() {
    if (!this.actions.publishEdit) {
      return;
    }
    this._fireAction(
      '/edit:publish',
      assertUIActionInfo(this.actions.publishEdit),
      false,
      {notify: NotifyType.NONE}
    );
  }

  _handleRebaseEditTap() {
    if (!this.actions.rebaseEdit) {
      return;
    }
    this._fireAction(
      '/edit:rebase',
      assertUIActionInfo(this.actions.rebaseEdit),
      false
    );
  }

  _handleHideBackgroundContent() {
    this.$.mainContent.classList.add('overlayOpen');
  }

  _handleShowBackgroundContent() {
    this.$.mainContent.classList.remove('overlayOpen');
  }

  /**
   * Merge sources of change actions into a single ordered array of action
   * values.
   */
  _computeAllActions(
    changeActionsRecord: PolymerDeepPropertyChange<
      ActionNameToActionInfoMap,
      ActionNameToActionInfoMap
    >,
    revisionActionsRecord: PolymerDeepPropertyChange<
      ActionNameToActionInfoMap,
      ActionNameToActionInfoMap
    >,
    primariesRecord: PolymerDeepPropertyChange<
      PrimaryActionKey[],
      PrimaryActionKey[]
    >,
    additionalActionsRecord: PolymerDeepPropertyChange<
      UIActionInfo[],
      UIActionInfo[]
    >,
    change?: ChangeInfo,
    config?: ServerInfo
  ): UIActionInfo[] {
    // Polymer 2: check for undefined
    if (
      [
        changeActionsRecord,
        revisionActionsRecord,
        primariesRecord,
        additionalActionsRecord,
        change,
      ].includes(undefined)
    ) {
      return [];
    }

    const revisionActionValues = this._getActionValues(
      revisionActionsRecord,
      primariesRecord,
      additionalActionsRecord,
      ActionType.REVISION
    );
    const changeActionValues = this._getActionValues(
      changeActionsRecord,
      primariesRecord,
      additionalActionsRecord,
      ActionType.CHANGE
    );
    const quickApprove = this._getQuickApproveAction();
    if (quickApprove) {
      changeActionValues.unshift(quickApprove);
    }

    return revisionActionValues
      .concat(changeActionValues)
      .sort((a, b) => this._actionComparator(a, b))
      .map(action => {
        if (ACTIONS_WITH_ICONS.has(action.__key)) {
          action.icon = action.__key;
        }
        // TODO(brohlfs): Temporary hack until change 269573 is live in all
        // backends.
        if (action.__key === ChangeActions.READY) {
          action.label = 'Mark as Active';
        }
        // End of hack
        return action;
      })
      .filter(action => !this._shouldSkipAction(action, config));
  }

  _getActionPriority(action: UIActionInfo) {
    if (action.__type && action.__key) {
      const overrideAction = this._actionPriorityOverrides.find(
        i => i.type === action.__type && i.key === action.__key
      );

      if (overrideAction !== undefined) {
        return overrideAction.priority;
      }
    }
    if (action.__key === 'review') {
      return ActionPriority.REVIEW;
    } else if (action.__primary) {
      return ActionPriority.PRIMARY;
    } else if (action.__type === ActionType.CHANGE) {
      return ActionPriority.CHANGE;
    } else if (action.__type === ActionType.REVISION) {
      return ActionPriority.REVISION;
    }
    return ActionPriority.DEFAULT;
  }

  /**
   * Sort comparator to define the order of change actions.
   */
  _actionComparator(actionA: UIActionInfo, actionB: UIActionInfo) {
    const priorityDelta =
      this._getActionPriority(actionA) - this._getActionPriority(actionB);
    // Sort by the button label if same priority.
    if (priorityDelta === 0) {
      return actionA.label > actionB.label ? 1 : -1;
    } else {
      return priorityDelta;
    }
  }

  _shouldSkipAction(action: UIActionInfo, config?: ServerInfo) {
    const skipActionKeys: string[] = [...SKIP_ACTION_KEYS];
    const isAttentionSetEnabled =
      !!config && !!config.change && config.change.enable_attention_set;
    if (isAttentionSetEnabled) {
      skipActionKeys.push(...SKIP_ACTION_KEYS_ATTENTION_SET);
    }
    return skipActionKeys.includes(action.__key);
  }

  _computeTopLevelActions(
    actionRecord: PolymerDeepPropertyChange<UIActionInfo[], UIActionInfo[]>,
    hiddenActionsRecord: PolymerDeepPropertyChange<string[], string[]>,
    editMode: boolean
  ): UIActionInfo[] {
    const hiddenActions = hiddenActionsRecord.base || [];
    return actionRecord.base.filter(a => {
      if (hiddenActions.includes(a.__key)) return false;
      if (editMode) return EDIT_ACTIONS.has(a.__key);
      return this._getActionOverflowIndex(a.__type, a.__key) === -1;
    });
  }

  _filterPrimaryActions(_topLevelActions: UIActionInfo[]) {
    this._topLevelPrimaryActions = _topLevelActions.filter(
      action => action.__primary
    );
    this._topLevelSecondaryActions = _topLevelActions.filter(
      action => !action.__primary
    );
  }

  _computeMenuActions(
    actionRecord: PolymerDeepPropertyChange<UIActionInfo[], UIActionInfo[]>,
    hiddenActionsRecord: PolymerDeepPropertyChange<string[], string[]>
  ): MenuAction[] {
    const hiddenActions = hiddenActionsRecord.base || [];
    return actionRecord.base
      .filter(a => {
        const overflow = this._getActionOverflowIndex(a.__type, a.__key) !== -1;
        return overflow && !hiddenActions.includes(a.__key);
      })
      .map(action => {
        let key = action.__key;
        if (key === '/') {
          key = 'delete';
        }
        return {
          name: action.label,
          id: `${key}-${action.__type}`,
          action,
          tooltip: action.title,
        };
      });
  }

  _computeRebaseOnCurrent(
    revisionRebaseAction: PropertyType<GrChangeActions, '_revisionRebaseAction'>
  ) {
    if (revisionRebaseAction) {
      return !!revisionRebaseAction.enabled;
    }
    return null;
  }

  /**
   * Occasionally, a change created by a change action is not yet known to the
   * API for a brief time. Wait for the given change number to be recognized.
   *
   * Returns a promise that resolves with true if a request is recognized, or
   * false if the change was never recognized after all attempts.
   *
   */
  _waitForChangeReachable(changeNum: NumericChangeId) {
    let attemptsRemaining = AWAIT_CHANGE_ATTEMPTS;
    return new Promise(resolve => {
      const check = () => {
        attemptsRemaining--;
        // Pass a no-op error handler to avoid the "not found" error toast.
        this.restApiService
          .getChange(changeNum, () => {})
          .then(response => {
            // If the response is 404, the response will be undefined.
            if (response) {
              resolve(true);
              return;
            }

            if (attemptsRemaining) {
              setTimeout(check, AWAIT_CHANGE_TIMEOUT_MS);
            } else {
              resolve(false);
            }
          });
      };
      check();
    });
  }

  _handleEditTap() {
    this.dispatchEvent(new CustomEvent('edit-tap', {bubbles: false}));
  }

  _handleStopEditTap() {
    this.dispatchEvent(new CustomEvent('stop-edit-tap', {bubbles: false}));
  }

  _computeHasTooltip(title?: string) {
    return !!title;
  }

  _computeHasIcon(action: UIActionInfo) {
    return action.icon ? '' : 'hidden';
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-change-actions': GrChangeActions;
  }
}
