/**
 * @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 '@polymer/iron-icon/iron-icon';
import '../../../styles/shared-styles';
import '../../shared/gr-dialog/gr-dialog';
import '../../shared/gr-overlay/gr-overlay';
import '../../shared/gr-rest-api-interface/gr-rest-api-interface';
import '../gr-diff/gr-diff';
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-apply-fix-dialog_html';
import {GerritNav} from '../../core/gr-navigation/gr-navigation';
import {customElement, property} from '@polymer/decorators';
import {ParsedChangeInfo} from '../../shared/gr-rest-api-interface/gr-reviewer-updates-parser';
import {
  NumericChangeId,
  EditPatchSetNum,
  FixId,
  FixSuggestionInfo,
  PatchSetNum,
  RobotId,
} from '../../../types/common';
import {DiffInfo, DiffPreferencesInfo} from '../../../types/diff';
import {GrOverlay} from '../../shared/gr-overlay/gr-overlay';
import {isRobot} from '../../../utils/comment-util';
import {OpenFixPreviewEvent} from '../../../types/events';
import {appContext} from '../../../services/app-context';

export interface GrApplyFixDialog {
  $: {
    applyFixOverlay: GrOverlay;
  };
}

interface FilePreview {
  filepath: string;
  preview: DiffInfo;
}

@customElement('gr-apply-fix-dialog')
export class GrApplyFixDialog extends GestureEventListeners(
  LegacyElementMixin(PolymerElement)
) {
  static get template() {
    return htmlTemplate;
  }

  @property({type: Object})
  prefs?: DiffPreferencesInfo;

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

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

  @property({type: Number})
  _patchNum?: PatchSetNum;

  @property({type: String})
  _robotId?: RobotId;

  @property({type: Object})
  _currentFix?: FixSuggestionInfo;

  @property({type: Array})
  _currentPreviews: FilePreview[] = [];

  @property({type: Array})
  _fixSuggestions?: FixSuggestionInfo[];

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

  @property({type: Number})
  _selectedFixIdx = 0;

  @property({
    type: Boolean,
    computed:
      '_computeDisableApplyFixButton(_isApplyFixLoading, change, ' +
      '_patchNum)',
  })
  _disableApplyFixButton?: boolean;

  private refitOverlay?: () => void;

  private restApiService = appContext.restApiService;

  /**
   * Given robot comment CustomEvent object, fetch diffs associated
   * with first robot comment suggested fix and open dialog.
   *
   * @param e to be passed from gr-comment with robot comment detail.
   * @return Promise that resolves either when all
   * preview diffs are fetched or no fix suggestions in custom event detail.
   */
  open(e: OpenFixPreviewEvent) {
    const detail = e.detail;
    const comment = detail.comment;
    if (!detail.patchNum || !comment || !isRobot(comment)) {
      return Promise.resolve();
    }
    this._patchNum = detail.patchNum;
    this._fixSuggestions = comment.fix_suggestions;
    this._robotId = comment.robot_id;
    if (!this._fixSuggestions || !this._fixSuggestions.length) {
      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.dispatchEvent(
        new CustomEvent('iron-resize', {
          composed: true,
          bubbles: true,
        })
      );
    });
  }

  attached() {
    super.attached();
    this.refitOverlay = () => {
      // re-center the dialog as content changed
      this.$.applyFixOverlay.dispatchEvent(
        new CustomEvent('iron-resize', {
          composed: true,
          bubbles: true,
        })
      );
    };
    this.addEventListener('diff-context-expanded', this.refitOverlay);
  }

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

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

  _fetchFixPreview(fixId: FixId) {
    if (!this.changeNum || !this._patchNum) {
      return Promise.reject(
        new Error('Both _patchNum and changeNum must be set')
      );
    }
    return this.restApiService
      .getRobotCommentFixPreview(this.changeNum, this._patchNum, fixId)
      .then(res => {
        if (res) {
          this._currentPreviews = Object.keys(res).map(key => {
            return {filepath: key, preview: res[key]};
          });
        }
      })
      .catch(err => {
        this._close();
        throw err;
      });
  }

  hasSingleFix(_fixSuggestions?: FixSuggestionInfo[]) {
    return (_fixSuggestions || []).length === 1;
  }

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

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

  addOneTo(_selectedFixIdx: number) {
    return _selectedFixIdx + 1;
  }

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

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

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

  _noNextFix(_selectedFixIdx: number, fixSuggestions?: FixSuggestionInfo[]) {
    if (!fixSuggestions) return true;
    return _selectedFixIdx === fixSuggestions.length - 1;
  }

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

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

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

  _computeTooltip(change?: ParsedChangeInfo, patchNum?: PatchSetNum) {
    if (!change || !patchNum) return '';
    const latestPatchNum = change.revisions[change.current_revision]._number;
    return latestPatchNum !== patchNum
      ? 'Fix can only be applied to the latest patchset'
      : '';
  }

  _computeDisableApplyFixButton(
    isApplyFixLoading?: boolean,
    change?: ParsedChangeInfo,
    patchNum?: PatchSetNum
  ) {
    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: CustomEvent) {
    if (e) {
      e.stopPropagation();
    }

    const changeNum = this.changeNum;
    const patchNum = this._patchNum;
    const change = this.change;
    if (!changeNum || !patchNum || !change || !this._currentFix) {
      return Promise.reject(new Error('Not all required properties are set.'));
    }
    this._isApplyFixLoading = true;
    return this.restApiService
      .applyFixSuggestion(changeNum, patchNum, this._currentFix.fix_id)
      .then(res => {
        if (res && res.ok) {
          GerritNav.navigateToChange(change, EditPatchSetNum, patchNum);
          this._close();
        }
        this._isApplyFixLoading = false;
      });
  }

  getFixDescription(currentFix?: FixSuggestionInfo) {
    return currentFix && currentFix.description ? currentFix.description : '';
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-apply-fix-dialog': GrApplyFixDialog;
  }
}
