/**
 * @license
 * Copyright (C) 2019 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 '../../../scripts/bundled-polymer.js';

import '@polymer/iron-icon/iron-icon.js';
import '../../../styles/shared-styles.js';
import '../../shared/gr-dialog/gr-dialog.js';
import '../../shared/gr-overlay/gr-overlay.js';
import '../../shared/gr-rest-api-interface/gr-rest-api-interface.js';
import '../gr-diff/gr-diff.js';
import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin.js';
import {PolymerElement} from '@polymer/polymer/polymer-element.js';
import {htmlTemplate} from './gr-apply-fix-dialog_html.js';
import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';

/**
 * @extends Polymer.Element
 */
class GrApplyFixDialog extends GestureEventListeners(
    LegacyElementMixin(PolymerElement)) {
  static get template() { return htmlTemplate; }

  static get is() { return 'gr-apply-fix-dialog'; }

  static get properties() {
    return {
      // Diff rendering preference API response.
      prefs: Array,
      // ChangeInfo API response object.
      change: Object,
      changeNum: String,
      _patchNum: Number,
      // robot ID associated with a robot comment.
      _robotId: String,
      // Selected FixSuggestionInfo entity from robot comment API response.
      _currentFix: Object,
      // Flattened /preview API response DiffInfo map object.
      _currentPreviews: {type: Array, value: () => []},
      // FixSuggestionInfo entities from robot comment API response.
      _fixSuggestions: Array,
      _isApplyFixLoading: {
        type: Boolean,
        value: false,
      },
      // Index of currently showing suggested fix.
      _selectedFixIdx: Number,
      _disableApplyFixButton: {
        type: Boolean,
        computed: '_computeDisableApplyFixButton(_isApplyFixLoading, change, '
          + '_patchNum)',
      },
    };
  }

  /**
   * Given robot comment CustomEvent objevt, fetch diffs associated
   * with first robot comment suggested fix and open dialog.
   *
   * @param {*} e CustomEvent to be passed from gr-comment with
   * robot comment detail.
   * @return {Promise<undefined>} Promise that resolves either when all
   * preview diffs are fetched or no fix suggestions in custom event detail.
   */
  open(e) {
    this._patchNum = e.detail.patchNum;
    this._fixSuggestions = e.detail.comment.fix_suggestions;
    this._robotId = e.detail.comment.robot_id;
    if (this._fixSuggestions == null || this._fixSuggestions.length == 0) {
      return Promise.resolve();
    }
    this._selectedFixIdx = 0;
    const promises = [];
    promises.push(
        this._showSelectedFixSuggestion(this._fixSuggestions[0]),
        this.$.applyFixOverlay.open()
    );
    return Promise.all(promises)
        .then(() => {
          // ensures gr-overlay repositions overlay in center
          this.$.applyFixOverlay.fire('iron-resize');
        });
  }

  attached() {
    super.attached();
    this.refitOverlay = () => {
      // re-center the dialog as content changed
      this.$.applyFixOverlay.fire('iron-resize');
    };
    this.addEventListener('diff-context-expanded', this.refitOverlay);
  }

  detached() {
    super.detached();
    this.removeEventListener('diff-context-expanded', this.refitOverlay);
  }

  _showSelectedFixSuggestion(fixSuggestion) {
    this._currentFix = fixSuggestion;
    return this._fetchFixPreview(fixSuggestion.fix_id);
  }

  _fetchFixPreview(fixId) {
    return this.$.restAPI
        .getRobotCommentFixPreview(this.changeNum, this._patchNum, fixId)
        .then(res => {
          if (res != null) {
            const previews = Object.keys(res).map(key => {
              return {filepath: key, preview: res[key]};
            });
            this._currentPreviews = previews;
          }
        })
        .catch(err => {
          this._close();
          throw err;
        });
  }

  hasSingleFix(_fixSuggestions) {
    return (_fixSuggestions || {}).length === 1;
  }

  overridePartialPrefs(prefs) {
    // generate a smaller gr-diff than fullscreen for dialog
    return Object.assign({}, prefs, {line_length: 50});
  }

  onCancel(e) {
    if (e) {
      e.stopPropagation();
    }
    this._close();
  }

  addOneTo(_selectedFixIdx) {
    return _selectedFixIdx + 1;
  }

  _onPrevFixClick(e) {
    if (e) e.stopPropagation();
    if (this._selectedFixIdx >= 1 && this._fixSuggestions != null) {
      this._selectedFixIdx -= 1;
      return this._showSelectedFixSuggestion(
          this._fixSuggestions[this._selectedFixIdx]);
    }
  }

  _onNextFixClick(e) {
    if (e) e.stopPropagation();
    if (this._fixSuggestions &&
      this._selectedFixIdx < this._fixSuggestions.length) {
      this._selectedFixIdx += 1;
      return this._showSelectedFixSuggestion(
          this._fixSuggestions[this._selectedFixIdx]);
    }
  }

  _noPrevFix(_selectedFixIdx) {
    return _selectedFixIdx === 0;
  }

  _noNextFix(_selectedFixIdx, fixSuggestions) {
    if (fixSuggestions == null) return true;
    return _selectedFixIdx === fixSuggestions.length - 1;
  }

  _close() {
    this._currentFix = {};
    this._currentPreviews = [];
    this._isApplyFixLoading = false;

    this.dispatchEvent(new CustomEvent('close-fix-preview', {
      bubbles: true,
      composed: true,
    }));
    this.$.applyFixOverlay.close();
  }

  _getApplyFixButtonLabel(isLoading) {
    return isLoading ? 'Saving...' : 'Apply Fix';
  }

  _computeTooltip(change, patchNum) {
    if (!change || patchNum == undefined) return '';
    // If change is defined, change.revisions and change.current_revisions
    // must be defined
    const latestPatchNum = change.revisions[change.current_revision]._number;
    return latestPatchNum !== patchNum ?
      'Fix can only be applied to the latest patchset' : '';
  }

  _computeDisableApplyFixButton(isApplyFixLoading, change, patchNum) {
    if (!change || isApplyFixLoading == undefined || patchNum == undefined) {
      return true;
    }
    const currentPatchNum = change.revisions[change.current_revision]._number;
    if (patchNum !== currentPatchNum) {
      return true;
    }
    return isApplyFixLoading;
  }

  _handleApplyFix(e) {
    if (e) {
      e.stopPropagation();
    }
    if (this._currentFix == null || this._currentFix.fix_id == null) {
      return;
    }
    this._isApplyFixLoading = true;
    return this.$.restAPI
        .applyFixSuggestion(
            this.changeNum, this._patchNum, this._currentFix.fix_id
        )
        .then(res => {
          if (res && res.ok) {
            GerritNav.navigateToChange(this.change, 'edit', this._patchNum);
            this._close();
          }
          this._isApplyFixLoading = false;
        });
  }

  getFixDescription(currentFix) {
    return currentFix != null && currentFix.description ?
      currentFix.description : '';
  }
}

customElements.define(GrApplyFixDialog.is, GrApplyFixDialog);
