/**
 * @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-js-api-interface/gr-js-api-interface';
import '../../shared/gr-overlay/gr-overlay';
import '../../shared/gr-rest-api-interface/gr-rest-api-interface';
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 {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners';
import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin';
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,
  patchNumEquals,
} from '../../../utils/patch-set-util';
import {
  changeIsOpen,
  ListChangesOption,
  listChangesOptionsToHex,
} from '../../../utils/change-util';
import {
  ChangeStatus,
  DraftsAction,
  HttpMethod,
  NotifyType,
} from '../../../constants/constants';
import {EventType, TargetElement} from '../../plugins/gr-plugin-types';
import {customElement, observe, property} from '@polymer/decorators';
import {GrJsApiInterface} from '../../shared/gr-js-api-interface/gr-js-api-interface-element';
import {
  ActionPriority,
  ActionType,
  ErrorCallback,
  RestApiService,
} from '../../../services/services/gr-rest-api/gr-rest-api';
import {
  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 {
  ChangeActions,
  GrChangeActionsElement,
  PrimaryActionKey,
  RevisionActions,
  UIActionInfo,
} from '../../shared/gr-js-api-interface/gr-change-actions-js-api';

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 isQuckApproveAction(
  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,
];

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;
}

export interface GrChangeActions {
  $: {
    jsAPI: GrJsApiInterface;
    restAPI: RestApiService & Element;
    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;
  };
}

@customElement('gr-change-actions')
export class GrChangeActions
  extends GestureEventListeners(LegacyElementMixin(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;

  @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: 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,
    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;

  /** @override */
  created() {
    super.created();
    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.$.restAPI.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.$.restAPI
      .getChangeRevisionActions(this.changeNum, this.latestPatchNum)
      .then(revisionActions => {
        if (!revisionActions) {
          return;
        }

        this.revisionActions = revisionActions;
        this._sendShowRevisionActions({
          change,
          revisionActions,
        });
        this._handleLoadingComplete();
      })
      .catch(err => {
        this.dispatchEvent(
          new CustomEvent('show-alert', {
            detail: {message: ERR_REVISION_ACTIONS},
            composed: true,
            bubbles: true,
          })
        );
        this._loading = false;
        throw err;
      });
  }

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

  _sendShowRevisionActions(detail: {
    change: ChangeInfo;
    revisionActions: ActionNameToActionInfoMap;
  }) {
    this.$.jsAPI.handleEvent(EventType.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);
        }
      } 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;
    }
    let result;
    for (const label in this.change.labels) {
      if (!(label in this.change.permitted_labels)) {
        continue;
      }
      if (this.change.permitted_labels[label].length === 0) {
        continue;
      }
      const status = this._getLabelStatus(this.change.labels[label]);
      if (status === LabelStatus.NEED) {
        if (result) {
          // More than one label is missing, so it's unclear which to quick
          // approve, return null;
          return null;
        }
        result = label;
      } else if (
        status === LabelStatus.REJECT ||
        status === LabelStatus.IMPOSSIBLE
      ) {
        return null;
      }
    }
    if (result) {
      const score = this.change.permitted_labels[result].slice(-1)[0];
      const labelInfo = this.change.labels[result];
      if (!isDetailedLabelInfo(labelInfo)) {
        return null;
      }
      const maxScore = Object.keys(labelInfo.values).slice(-1)[0];
      if (score === maxScore) {
        // Allow quick approve only for maximal score.
        return {
          label: result,
          score,
        };
      }
    }
    return null;
  }

  hideQuickApproveAction() {
    if (!this._topLevelSecondaryActions) {
      throw new Error('_topLevelSecondaryActions must be set');
    }
    this._topLevelSecondaryActions = this._topLevelSecondaryActions.filter(
      sa => !isQuckApproveAction(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.$.restAPI
      .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 (patchNumEquals(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.$.restAPI.getChanges(0, query).then(changes => {
      if (!changes) {
        console.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.$.restAPI.getChanges(0, query).then(changes => {
      if (!changes) {
        console.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(isQuckApproveAction);
        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) {
      this.dispatchEvent(
        new CustomEvent('show-alert', {
          detail: {message: ERR_BRANCH_EMPTY},
          composed: true,
          bubbles: true,
        })
      );
      return;
    }
    if (!el.message) {
      this.dispatchEvent(
        new CustomEvent('show-alert', {
          detail: {message: ERR_COMMIT_EMPTY},
          composed: true,
          bubbles: true,
        })
      );
      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) {
      this.dispatchEvent(
        new CustomEvent('show-alert', {
          detail: {message: ERR_BRANCH_EMPTY},
          composed: true,
          bubbles: true,
        })
      );
      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:
        console.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();

    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.
  _setLabelValuesOnRevert(newChangeId: NumericChangeId) {
    const labels = this.$.jsAPI.getLabelValuesPostRevert(this.change);
    if (!labels) {
      return Promise.resolve(undefined);
    }
    return this.$.restAPI.saveChangeReview(newChangeId, 'current', {labels});
  }

  _handleResponse(action: UIActionInfo, response?: Response) {
    if (!response) {
      return;
    }
    return this.$.restAPI.getResponseObject(response).then(obj => {
      switch (action.__key) {
        case ChangeActions.REVERT: {
          const revertChangeInfo: ChangeInfo = (obj as unknown) as ChangeInfo;
          this._waitForChangeReachable(revertChangeInfo._number)
            .then(() => this._setLabelValuesOnRevert(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.$.restAPI).then(result => {
      if (!result.isLatest) {
        this.dispatchEvent(
          new CustomEvent('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.$.restAPI
        .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.$.restAPI.getChanges(0, query, undefined, options).then(changes => {
      if (!changes) {
        console.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 attempsRemaining = AWAIT_CHANGE_ATTEMPTS;
    return new Promise(resolve => {
      const check = () => {
        attempsRemaining--;
        // Pass a no-op error handler to avoid the "not found" error toast.
        this.$.restAPI
          .getChange(changeNum, () => {})
          .then(response => {
            // If the response is 404, the response will be undefined.
            if (response) {
              resolve(true);
              return;
            }

            if (attempsRemaining) {
              this.async(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;
  }
}
