(function() {
  'use strict';

  const Defs = {};

  const Statuses = window.Gerrit.Checks.Statuses;
  const StatusPriorityOrder = [
    Statuses.FAILED,
    Statuses.SCHEDULED,
    Statuses.RUNNING,
    Statuses.SUCCESSFUL,
    Statuses.NOT_STARTED,
    Statuses.NOT_RELEVANT,
  ];

  const STATE_ALL = 'ALL';
  const CheckStateFilters = [STATE_ALL, ...StatusPriorityOrder];

  const CHECKS_POLL_INTERVAL_MS = 60 * 1000;
  const CHECKS_LIMIT = 20;

  /**
   * @typedef {{
   *   _number: number,
   * }}
   */
  Defs.Change;
  /**
   * @typedef {{
   *   _number: number,
   * }}
   */
  Defs.Revision;

  const LoadingStatus = {
    LOADING: 0,
    EMPTY: 1,
    RESULTS: 2,
    NOT_CONFIGURED: 3,
  };

  Polymer({
    is: 'gr-checks-view',

    properties: {
      revision: {
        type: Object,
        observer: '_handleRevisionUpdate',
      },
      change: Object,
      /** @type {function(number, number): !Promise<!Object>} */
      getChecks: Function,
      /** @type {function(string): !Promise<Boolean>} */
      isConfigured: Function,
      /** @type {function(string, string): !Promise<!Object>} */
      pluginRestApi: Object,
      _checks: Array,
      _status: {
        type: Object,
        value: LoadingStatus.LOADING,
      },
      _visibleChecks: {
        type: Array,
      },
      _statuses: Array,
      pollChecksInterval: Number,
      visibilityChangeListenerAdded: {
        type: Boolean,
        value: false,
      },
      _createCheckerCapability: {
        type: Boolean,
        value: false,
      },
      _patchSetDropdownItems: {
        type: Array,
        value() { return []; },
        computed: '_computePatchSetDropdownItems(change)',
      },
      _currentPatchSet: {
        type: Number,
      },
      _currentStatus: {
        type: String,
        value: STATE_ALL,
      },
      _showBlockingChecksOnly: {
        type: Boolean,
        value: false,
      },
      _showAllChecks: {
        type: Boolean,
        value: false,
      },
      _filteredChecks: Array,
      _showMoreChecksButton: {
        type: Boolean,
        value: false,
        notify: true,
      },
    },

    observers: [
      '_pollChecksRegularly(change, _currentPatchSet, getChecks)',
      '_updateVisibleChecks(_checks.*, _currentStatus, ' +
          '_showBlockingChecksOnly, _showAllChecks)',
    ],

    attached() {
      this.pluginRestApi = this.plugin.restApi();
      this._statuses = CheckStateFilters.map(state => {
        return {
          text: state,
          value: state,
        };
      });
      this._initCreateCheckerCapability();
    },

    detached() {
      clearInterval(this.pollChecksInterval);
      this.unlisten(document, 'visibilitychange', '_onVisibililityChange');
    },

    _toggleShowChecks() {
      this._showAllChecks = !this._showAllChecks;
    },

    _computePatchSetDropdownItems(change) {
      return Object.values(change.revisions)
          .filter(patch => patch._number !== 'edit')
          .map(patch => {
            return {
              text: 'Patchset ' + patch._number,
              value: patch._number,
            };
          })
          .sort((a, b) => b.value - a.value);
    },

    _computeShowText(showAllChecks) {
      return showAllChecks ? 'Show Less' : 'Show All';
    },

    _updateVisibleChecks(checksRecord, status, showBlockingChecksOnly,
        showAllChecks) {
      const checks = checksRecord.base;
      if (!checks) return [];
      this._filteredChecks = checks.filter(check => {
        if (showBlockingChecksOnly && (!check.blocking ||
            !check.blocking.length)) return false;
        return status === STATE_ALL || check.state === status;
      });
      /* The showCheckMessage property is notified for change because the
      changes to showCheckMessage are not reflected to the dom as the object
      check has the same reference as before
      If not notified, then the message for the check is not displayed after
      clicking the toggle
      */
      this._showMoreChecksButton = this._filteredChecks.length > CHECKS_LIMIT;
      this._visibleChecks = this._filteredChecks.slice(0, showAllChecks ?
        undefined : CHECKS_LIMIT);
      this._visibleChecks.forEach((val, idx) =>
        this.notifyPath(`_visibleChecks.${idx}.showCheckMessage`));
    },

    _handleRevisionUpdate(revision) {
      this._currentPatchSet = revision._number;
    },

    _handlePatchSetChanged(e) {
      // gr-dropdown-list returns value of type "String"
      const patchSet = parseInt(e.detail.value);
      if (patchSet === this._currentPatchSet) return;
      this._currentPatchSet = patchSet;
    },

    _handleBlockingCheckboxClicked() {
      this._showBlockingChecksOnly = !this._showBlockingChecksOnly;
    },

    _handleStatusFilterChanged(e) {
      const status = e.detail.value;
      if (status === this._currentStatus) return;
      this._currentStatus = status;
    },

    _handleCheckersListResize() {
      // Force polymer to recalculate position of overlay when length of
      // checkers changes
      this.$.listOverlay.refit();
    },

    _initCreateCheckerCapability() {
      return this.pluginRestApi.getAccount().then(account => {
        if (!account) { return; }
        return this.pluginRestApi
            .getAccountCapabilities(['checks-administrateCheckers'])
            .then(capabilities => {
              if (capabilities['checks-administrateCheckers']) {
                this._createCheckerCapability = true;
              }
            });
      });
    },

    _handleConfigureClicked() {
      this.$$('gr-checkers-list')._showConfigureOverlay();
    },

    _orderChecks(a, b) {
      if (a.state != b.state) {
        const indexA = StatusPriorityOrder.indexOf(a.state);
        const indexB = StatusPriorityOrder.indexOf(b.state);
        if (indexA != -1 && indexB != -1) {
          return indexA - indexB;
        }
        return indexA == -1 ? 1 : -1;
      }
      if (a.state === Statuses.FAILED) {
        if (a.blocking && b.blocking &&
            a.blocking.length !== b.blocking.length) {
          return a.blocking.length == 0 ? 1 : -1;
        }
      }
      return a.checker_name.localeCompare(b.checker_name);
    },

    _handleRetryCheck(e) {
      const uuid = e.detail.uuid;
      const retryCheck = (change, revision, uuid) => this.pluginRestApi.post(
          '/changes/' + change + '/revisions/' + revision + '/checks/' + uuid
              + '/rerun'
      );
      retryCheck(this.change._number, this.revision._number, uuid).then(
          res => {
            this._fetchChecks(this.change, this.revision._number,
                this.getChecks);
          }, error => {
            this.fire('show-error', {message: error.message});
          }
      );
    },

    /**
     * Merge new checks into old checks to maintain showCheckMessage
     * property
     * Loop over checks to make sure no new checks are missed
     * Merge new check object into prev check
     * Remove any check that is not returned the next time
     * Ensure message is updated
     */
    _updateChecks(checks) {
      return checks.map(
          check => {
            const prevCheck = this._checks.find(
                c => c.checker_uuid === check.checker_uuid
            );
            if (!prevCheck) return Object.assign({}, check);
            return Object.assign({}, prevCheck, check,
                {showCheckMessage: prevCheck.showCheckMessage});
          });
    },

    /**
     * @param {!Defs.Change} change
     * @param {!Defs.Revision} revision
     * @param {function(number, number): !Promise<!Object>} getChecks
     */
    _fetchChecks(change, revisionNumber, getChecks) {
      if (!getChecks || !change || !revisionNumber) return;

      getChecks(change._number, revisionNumber).then(checks => {
        if (revisionNumber !== this._currentPatchSet) return;
        if (checks && checks.length) {
          checks.sort((a, b) => this._orderChecks(a, b));
          if (!this._checks) {
            this._checks = checks;
          } else {
            this._checks = this._updateChecks(checks);
          }
          this.set('_status', LoadingStatus.RESULTS);
        } else {
          this._checkConfigured();
        }
      }, error => {
        this._checks = [];
        this.set('_status', LoadingStatus.EMPTY);
      });
    },

    _onVisibililityChange() {
      if (document.hidden) {
        clearInterval(this.pollChecksInterval);
        return;
      }
      this._pollChecksRegularly(this.change, this._currentPatchSet,
          this.getChecks);
    },

    _toggleCheckMessage(e) {
      const uuid = e.detail.uuid;
      if (!uuid) {
        console.warn('uuid not found');
        return;
      }
      const idx = this._checks.findIndex(check => check.checker_uuid === uuid);
      if (idx == -1) {
        console.warn('check not found');
        return;
      }
      // Update subproperty of _checks[idx] so that it reflects to polymer
      this.set(`_checks.${idx}.showCheckMessage`,
          !this._checks[idx].showCheckMessage);
    },

    _pollChecksRegularly(change, revisionNumber, getChecks) {
      if (!change || !revisionNumber || !getChecks) return;
      if (this.pollChecksInterval) {
        clearInterval(this.pollChecksInterval);
      }
      const poll = () => this._fetchChecks(change, revisionNumber, getChecks);
      poll();
      this.pollChecksInterval = setInterval(poll, CHECKS_POLL_INTERVAL_MS);
      if (!this.visibilityChangeListenerAdded) {
        this.visibilityChangeListenerAdded = true;
        this.listen(document, 'visibilitychange', '_onVisibililityChange');
      }
    },

    _checkConfigured() {
      const repository = this.change['project'];
      this.isConfigured(repository).then(configured => {
        const status =
            configured ? LoadingStatus.EMPTY : LoadingStatus.NOT_CONFIGURED;
        this.set('_status', status);
      });
    },

    _isLoading(status) {
      return status === LoadingStatus.LOADING;
    },

    _isEmpty(status) {
      return status === LoadingStatus.EMPTY;
    },

    _hasResults(status) {
      return status === LoadingStatus.RESULTS;
    },

    _isNotConfigured(status) {
      return status === LoadingStatus.NOT_CONFIGURED;
    },

    _computeHeaderClass(currentPatchSet, sortedAllPatchsets) {
      if (!sortedAllPatchsets
         || sortedAllPatchsets.length < 1
          || !currentPatchSet) {
        return '';
      }
      return currentPatchSet === sortedAllPatchsets[0].value ?
        '' : 'oldPatchset';
    },
  });
})();
