/**
 * @license
 * Copyright (C) 2020 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 {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 {pluginLoader} from './gr-plugin-loader.js';
import {patchNumEquals} from '../../../utils/patch-set-util.js';

// Note: for new events, naming convention should be: `a-b`
const EventType = {
  HISTORY: 'history',
  LABEL_CHANGE: 'labelchange',
  SHOW_CHANGE: 'showchange',
  SUBMIT_CHANGE: 'submitchange',
  SHOW_REVISION_ACTIONS: 'show-revision-actions',
  COMMIT_MSG_EDIT: 'commitmsgedit',
  COMMENT: 'comment',
  REVERT: 'revert',
  REVERT_SUBMISSION: 'revert_submission',
  POST_REVERT: 'postrevert',
  ANNOTATE_DIFF: 'annotatediff',
  ADMIN_MENU_LINKS: 'admin-menu-links',
  HIGHLIGHTJS_LOADED: 'highlightjs-loaded',
};

const Element = {
  CHANGE_ACTIONS: 'changeactions',
  REPLY_DIALOG: 'replydialog',
};

/**
 * @extends PolymerElement
 */
class GrJsApiInterface extends GestureEventListeners(
    LegacyElementMixin(
        PolymerElement)) {
  static get is() { return 'gr-js-api-interface'; }

  constructor() {
    super();
    this.Element = Element;
    this.EventType = EventType;
  }

  static get properties() {
    return {
      _elements: {
        type: Object,
        value: {}, // Shared across all instances.
      },
      _eventCallbacks: {
        type: Object,
        value: {}, // Shared across all instances.
      },
    };
  }

  handleEvent(type, detail) {
    pluginLoader.awaitPluginsLoaded().then(() => {
      switch (type) {
        case EventType.HISTORY:
          this._handleHistory(detail);
          break;
        case EventType.SHOW_CHANGE:
          this._handleShowChange(detail);
          break;
        case EventType.COMMENT:
          this._handleComment(detail);
          break;
        case EventType.LABEL_CHANGE:
          this._handleLabelChange(detail);
          break;
        case EventType.SHOW_REVISION_ACTIONS:
          this._handleShowRevisionActions(detail);
          break;
        case EventType.HIGHLIGHTJS_LOADED:
          this._handleHighlightjsLoaded(detail);
          break;
        default:
          console.warn('handleEvent called with unsupported event type:',
              type);
          break;
      }
    });
  }

  addElement(key, el) {
    this._elements[key] = el;
  }

  getElement(key) {
    return this._elements[key];
  }

  addEventCallback(eventName, callback) {
    if (!this._eventCallbacks[eventName]) {
      this._eventCallbacks[eventName] = [];
    }
    this._eventCallbacks[eventName].push(callback);
  }

  canSubmitChange(change, revision) {
    const submitCallbacks = this._getEventCallbacks(EventType.SUBMIT_CHANGE);
    const cancelSubmit = submitCallbacks.some(callback => {
      try {
        return callback(change, revision) === false;
      } catch (err) {
        console.error(err);
      }
      return false;
    });

    return !cancelSubmit;
  }

  _removeEventCallbacks() {
    for (const k in EventType) {
      if (!EventType.hasOwnProperty(k)) { continue; }
      this._eventCallbacks[EventType[k]] = [];
    }
  }

  _handleHistory(detail) {
    for (const cb of this._getEventCallbacks(EventType.HISTORY)) {
      try {
        cb(detail.path);
      } catch (err) {
        console.error(err);
      }
    }
  }

  _handleShowChange(detail) {
    // Note (issue 8221) Shallow clone the change object and add a mergeable
    // getter with deprecation warning. This makes the change detail appear as
    // though SKIP_MERGEABLE was not set, so that plugins that expect it can
    // still access.
    //
    // This clone and getter can be removed after plugins migrate to use
    // info.mergeable.
    //
    // assign on getter with existing property will report error
    // see Issue: 12286
    const change = {...detail.change, get mergeable() {
      console.warn('Accessing change.mergeable from SHOW_CHANGE is ' +
            'deprecated! Use info.mergeable instead.');
      return detail.info && detail.info.mergeable;
    }};
    const patchNum = detail.patchNum;
    const info = detail.info;

    let revision;
    for (const rev of Object.values(change.revisions || {})) {
      if (patchNumEquals(rev._number, patchNum)) {
        revision = rev;
        break;
      }
    }

    for (const cb of this._getEventCallbacks(EventType.SHOW_CHANGE)) {
      try {
        cb(change, revision, info);
      } catch (err) {
        console.error(err);
      }
    }
  }

  /**
   * @param {!{change: !Object, revisionActions: !Object}} detail
   */
  _handleShowRevisionActions(detail) {
    const registeredCallbacks = this._getEventCallbacks(
        EventType.SHOW_REVISION_ACTIONS
    );
    for (const cb of registeredCallbacks) {
      try {
        cb(detail.revisionActions, detail.change);
      } catch (err) {
        console.error(err);
      }
    }
  }

  handleCommitMessage(change, msg) {
    for (const cb of this._getEventCallbacks(EventType.COMMIT_MSG_EDIT)) {
      try {
        cb(change, msg);
      } catch (err) {
        console.error(err);
      }
    }
  }

  _handleComment(detail) {
    for (const cb of this._getEventCallbacks(EventType.COMMENT)) {
      try {
        cb(detail.node);
      } catch (err) {
        console.error(err);
      }
    }
  }

  _handleLabelChange(detail) {
    for (const cb of this._getEventCallbacks(EventType.LABEL_CHANGE)) {
      try {
        cb(detail.change);
      } catch (err) {
        console.error(err);
      }
    }
  }

  _handleHighlightjsLoaded(detail) {
    for (const cb of this._getEventCallbacks(EventType.HIGHLIGHTJS_LOADED)) {
      try {
        cb(detail.hljs);
      } catch (err) {
        console.error(err);
      }
    }
  }

  modifyRevertMsg(change, revertMsg, origMsg) {
    for (const cb of this._getEventCallbacks(EventType.REVERT)) {
      try {
        revertMsg = cb(change, revertMsg, origMsg);
      } catch (err) {
        console.error(err);
      }
    }
    return revertMsg;
  }

  modifyRevertSubmissionMsg(change, revertSubmissionMsg, origMsg) {
    for (const cb of this._getEventCallbacks(EventType.REVERT_SUBMISSION)) {
      try {
        revertSubmissionMsg = cb(change, revertSubmissionMsg, origMsg);
      } catch (err) {
        console.error(err);
      }
    }
    return revertSubmissionMsg;
  }

  getDiffLayers(path, changeNum, patchNum) {
    const layers = [];
    for (const annotationApi of
      this._getEventCallbacks(EventType.ANNOTATE_DIFF)) {
      try {
        const layer = annotationApi.getLayer(path, changeNum, patchNum);
        layers.push(layer);
      } catch (err) {
        console.error(err);
      }
    }
    return layers;
  }

  disposeDiffLayers(path) {
    for (const annotationApi of
      this._getEventCallbacks(EventType.ANNOTATE_DIFF)) {
      try {
        annotationApi.disposeLayer(path);
      } catch (err) {
        console.error(err);
      }
    }
  }

  /**
   * Retrieves coverage data possibly provided by a plugin.
   *
   * Will wait for plugins to be loaded. If multiple plugins offer a coverage
   * provider, the first one is returned. If no plugin offers a coverage provider,
   * will resolve to null.
   *
   * @return {!Promise<?GrAnnotationActionsInterface>}
   */
  getCoverageAnnotationApi() {
    return pluginLoader.awaitPluginsLoaded()
        .then(() => this._getEventCallbacks(EventType.ANNOTATE_DIFF)
            .find(api => api.getCoverageProvider()));
  }

  getAdminMenuLinks() {
    const links = [];
    for (const adminApi of
      this._getEventCallbacks(EventType.ADMIN_MENU_LINKS)) {
      links.push(...adminApi.getMenuLinks());
    }
    return links;
  }

  getLabelValuesPostRevert(change) {
    let labels = {};
    for (const cb of this._getEventCallbacks(EventType.POST_REVERT)) {
      try {
        labels = cb(change);
      } catch (err) {
        console.error(err);
      }
    }
    return labels;
  }

  _getEventCallbacks(type) {
    return this._eventCallbacks[type] || [];
  }
}

customElements.define(GrJsApiInterface.is, GrJsApiInterface);
