/**
 * @license
 * Copyright (C) 2017 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.
 */
(function() {
  'use strict';

  // Maximum length for patch set descriptions.
  const PATCH_DESC_MAX_LENGTH = 500;
  const MERGED_STATUS = 'MERGED';

  Polymer({
    is: 'gr-file-list-header',
    _legacyUndefinedCheck: true,

    /**
     * @event expand-diffs
     */

    /**
     * @event collapse-diffs
     */

    /**
     * @event open-diff-prefs
     */

    /**
     * @event open-included-in-dialog
     */

    /**
     * @event open-download-dialog
     */

    /**
     * @event open-upload-help-dialog
     */

    properties: {
      account: Object,
      allPatchSets: Array,
      /** @type {?} */
      change: Object,
      changeNum: String,
      changeUrl: String,
      changeComments: Object,
      commitInfo: Object,
      editMode: Boolean,
      loggedIn: Boolean,
      serverConfig: Object,
      shownFileCount: Number,
      diffPrefs: Object,
      diffPrefsDisabled: Boolean,
      diffViewMode: {
        type: String,
        notify: true,
      },
      patchNum: String,
      basePatchNum: String,
      filesExpanded: String,
      // Caps the number of files that can be shown and have the 'show diffs' /
      // 'hide diffs' buttons still be functional.
      _maxFilesForBulkActions: {
        type: Number,
        readOnly: true,
        value: 225,
      },
      _patchsetDescription: {
        type: String,
        value: '',
      },
      showTitle: {
        type: Boolean,
        value: true,
      },
      _descriptionReadOnly: {
        type: Boolean,
        computed: '_computeDescriptionReadOnly(loggedIn, change, account)',
      },
      revisionInfo: Object,
    },

    behaviors: [
      Gerrit.PatchSetBehavior,
    ],

    observers: [
      '_computePatchSetDescription(change, patchNum)',
    ],

    setDiffViewMode(mode) {
      this.$.modeSelect.setMode(mode);
    },

    _expandAllDiffs() {
      this._expanded = true;
      this.fire('expand-diffs');
    },

    _collapseAllDiffs() {
      this._expanded = false;
      this.fire('collapse-diffs');
    },

    _computeExpandedClass(filesExpanded) {
      const classes = [];
      if (filesExpanded === GrFileListConstants.FilesExpandedState.ALL) {
        classes.push('expanded');
      }
      if (filesExpanded === GrFileListConstants.FilesExpandedState.SOME ||
            filesExpanded === GrFileListConstants.FilesExpandedState.ALL) {
        classes.push('openFile');
      }
      return classes.join(' ');
    },

    _computeDescriptionPlaceholder(readOnly) {
      return (readOnly ? 'No' : 'Add') + ' patchset description';
    },

    _computeDescriptionReadOnly(loggedIn, change, account) {
      return !(loggedIn && (account._account_id === change.owner._account_id));
    },

    _computePatchSetDescription(change, patchNum) {
      const rev = this.getRevisionByPatchNum(change.revisions, patchNum);
      this._patchsetDescription = (rev && rev.description) ?
        rev.description.substring(0, PATCH_DESC_MAX_LENGTH) : '';
    },

    _handleDescriptionRemoved(e) {
      return this._updateDescription('', e);
    },

    /**
     * @param {!Object} revisions The revisions object keyed by revision hashes
     * @param {?Object} patchSet A revision already fetched from {revisions}
     * @return {string|undefined} the SHA hash corresponding to the revision.
     */
    _getPatchsetHash(revisions, patchSet) {
      for (const rev in revisions) {
        if (revisions.hasOwnProperty(rev) &&
            revisions[rev] === patchSet) {
          return rev;
        }
      }
    },

    _handleDescriptionChanged(e) {
      const desc = e.detail.trim();
      this._updateDescription(desc, e);
    },

    /**
     * Update the patchset description with the rest API.
     *
     * @param {string} desc
     * @param {?(Event|Node)} e
     * @return {!Promise}
     */
    _updateDescription(desc, e) {
      const target = Polymer.dom(e).rootTarget;
      if (target) { target.disabled = true; }
      const rev = this.getRevisionByPatchNum(this.change.revisions,
          this.patchNum);
      const sha = this._getPatchsetHash(this.change.revisions, rev);
      return this.$.restAPI.setDescription(this.changeNum, this.patchNum, desc)
          .then(res => {
            if (res.ok) {
              if (target) { target.disabled = false; }
              this.set(['change', 'revisions', sha, 'description'], desc);
              this._patchsetDescription = desc;
            }
          }).catch(err => {
            if (target) { target.disabled = false; }
            return;
          });
    },

    _computePrefsButtonHidden(prefs, diffPrefsDisabled) {
      return diffPrefsDisabled || !prefs;
    },

    _fileListActionsVisible(shownFileCount, maxFilesForBulkActions) {
      return shownFileCount <= maxFilesForBulkActions;
    },

    _handlePatchChange(e) {
      const {basePatchNum, patchNum} = e.detail;
      if (this.patchNumEquals(basePatchNum, this.basePatchNum) &&
          this.patchNumEquals(patchNum, this.patchNum)) { return; }
      Gerrit.Nav.navigateToChange(this.change, patchNum, basePatchNum);
    },

    _handlePrefsTap(e) {
      e.preventDefault();
      this.fire('open-diff-prefs');
    },

    _handleIncludedInTap(e) {
      e.preventDefault();
      this.fire('open-included-in-dialog');
    },

    _handleDownloadTap(e) {
      e.preventDefault();
      this.dispatchEvent(
          new CustomEvent('open-download-dialog', {bubbles: false}));
    },

    _computeEditModeClass(editMode) {
      return editMode ? 'editMode' : '';
    },

    _computePatchInfoClass(patchNum, allPatchSets) {
      const latestNum = this.computeLatestPatchNum(allPatchSets);
      if (this.patchNumEquals(patchNum, latestNum)) {
        return '';
      }
      return 'patchInfoOldPatchSet';
    },

    _hideIncludedIn(change) {
      return change && change.status === MERGED_STATUS ? '' : 'hide';
    },

    _handleUploadTap(e) {
      e.preventDefault();
      this.dispatchEvent(
          new CustomEvent('open-upload-help-dialog', {bubbles: false}));
    },

    _computeUploadHelpContainerClass(change, account) {
      const changeIsMerged = change && change.status === MERGED_STATUS;
      const ownerId = change && change.owner && change.owner._account_id ?
        change.owner._account_id : null;
      const userId = account && account._account_id;
      const userIsOwner = ownerId && userId && ownerId === userId;
      const hideContainer = !userIsOwner || changeIsMerged;
      return 'uploadContainer desktop' + (hideContainer ? ' hide' : '');
    },
  });
})();
