(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) {
      if (!revision) return;
      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';
    },
  });
})();
