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

  const DEFAULT_UPDATE_INTERVAL_MS = 1000 * 2;
  const MAX_UPDATE_INTERVAL_MS = 1000 * 30 * 2;

  /**
   * Wrapper around localStorage to prevent using it if you have it disabled.
   *
   * Temporary until https://gerrit-review.googlesource.com/c/gerrit/+/211472 is merged.
   *
   */
  class ZuulSiteBasedStorage {
    // Returns the local storage.
    _storage() {
      try {
        return window.localStorage;
      } catch (err) {
        console.error('localStorage is disabled with this error ' + err);
        return null;
      }
    }

    getItem(key) {
      if (this._storage() === null) { return null; }
      return this._storage().getItem(key);
    }

    setItem(key, value) {
      if (this._storage() === null) { return null; }
      return this._storage().setItem(key, value);
    }

    removeItem(key) {
      if (this._storage() === null) { return null; }
      return this._storage().removeItem(key);
    }

    clear() {
      if (this._storage() === null) { return null; }
      return this._storage().clear();
    }
  }

  Polymer({
    is: 'zuul-status-view',
    _legacyUndefinedCheck: true,

    properties: {
      zuulUrl: String,
      zuulTenant: {
        type: String,
        value: null,
      },
      plugin: Object,
      change: Object,
      revision: {
        type: Object,
        observer: 'reload',
      },
      _needsUpdate: {
        type: Boolean,
        value: false,
      },
      _response: Array,
      _updateIntervalMs: {
        type: Number,
        value: DEFAULT_UPDATE_INTERVAL_MS,
      },
      // Start time is the time that this element was loaded,
      // used to determine how long we've been trying to update.
      _startTime: Date,
      _updateTimeoutID: Number,
      _storage: {
        type: Object,
        value: new ZuulSiteBasedStorage(),
      },
      zuulDisable: {
        type: Boolean,
        value: false,
      }
    },

    attached() {
      this.listen(document, 'visibilitychange', '_handleVisibilityChange');
      if (!this.change || !this.revision) {
        console.warn('element attached without change and revision set.');
        return;
      }
    },

    detached() {
      this._clearUpdateTimeout();
    },

    /**
     * Reset the state of the element, then fetch and display progress.
     *
     * @return {Promise} Resolves upon completion.
     */
    async reload() {
      this._response = null;
      this._startTime = new Date();

      if (this._storage.getItem('disable_zuul_status')) {
        this.set('zuulDisable', true);
      } else {
        this.set('zuulDisable', false);
      }

      const project = this.change.project;
      const plugin = this.plugin.getPluginName();
      const config = await this.getConfig(project, plugin);
      if (config && config.zuul_url) {
        this.zuulUrl = config.zuul_url;
        if (config.zuul_tenant) {
          this.zuulTenant = config.zuul_tenant;
          console.info(`zuul-status: Zuul v3 at ${this.zuulUrl}, tenant ${this.zuulTenant}`);
        } else {
          console.info(`zuul-status: Zuul v2 at ${this.zuulUrl}`);
        }
      } else {
        console.info("No config found for plugin zuul-status");
      }
      if (this.zuulUrl) {
        await this._update();
      }
    },

    /**
     * Fetch the config for this plugin
     *
     * @return {Promise} Resolves to the fetched config object,
     *     or rejects if the response is non-OK.
     */
    async getConfig(project, plugin) {
      return await this.plugin.restApi().get(
              `/projects/${encodeURIComponent(project)}` +
              `/${encodeURIComponent(plugin)}~config`);
    },

    /**
     * Fetch current progress state and update properties.
     *
     * @return {Promise} Resolves upon completion.
     */
    async _update() {
      try {
        const response = await this.getZuulStatus(this.change, this.revision);
        this._response = response.map((results, i) => ({
          name: results.jobs[i].pipeline,
          results,
        }));
        this._updateIntervalMs = DEFAULT_UPDATE_INTERVAL_MS;
      } catch (err) {
        this._updateIntervalMs = Math.min(
            MAX_UPDATE_INTERVAL_MS,
            (1 + Math.random()) * this._updateIntervalMs * 2);
        console.warn(err);
      }
      this._resetTimeout();
    },

    /**
     * Makes a request to the zuul server to get the status on the change.
     *
     * @param {ChangeInfo} change The current CL.
     * @param {RevisionInfo} revision The current patchset.
     * @return {Promise} Resolves to a fetch Response object.
     */
    async getZuulStatus(change, revision) {
      const response = await this._getReponse(change, revision);

      if (response && response.status && response.status === 200) {
        const text = await response.text();
        return await JSON.parse(text);
      }

      return [];
    },

    /**
     * Makes a GET request to the zuul server.
     *
     * @param {ChangeInfo} change change The current CL.
     * @param {RevisionInfo} revision The current patchset.
     * @return {Promise} Resolves to a fetch Response object.
     */
    async _getReponse(change, revision) {
      const url = this.zuulTenant === null ?
        `${this.zuulUrl}${change._number},${revision._number}` :
        `${this.zuulUrl}/api/tenant/${this.zuulTenant}/status/change/${change._number},${revision._number}`;
      const options = {method: 'GET'};

      return await fetch(url, options);
    },

    /**
     * Set a timeout to update again if applicable.
     */
    _resetTimeout() {
      this._clearUpdateTimeout();

      if (this._response === []) {
        return;
      }

      this._updateTimeoutID = window.setTimeout(
          this._updateTimeoutFired.bind(this),
          this._updateIntervalMs);
    },

    _clearUpdateTimeout() {
      if (this._updateTimeoutID) {
        window.clearTimeout(this._updateTimeoutID);
        this._updateTimeoutID = null;
      }
    },

    _handleVisibilityChange(e) {
      if (!document.hidden && this._needsUpdate) {
        this._update();
        this._needsUpdate = false;
      }
    },

    _updateTimeoutFired() {
      if (document.hidden) {
        this._needsUpdate = true;
        return;
      }

      this._update();
    },

    /**
     * Return a string to show as the bold title in the UI.
     */
    _computeTitle(response) {
      if (!response) {
        return 'No Zuul Status Results';
      }

      return 'Zuul Status';
    },

    /**
     * Check whether the response contains report_url.
     *
     * @return {String} True when we are done requesting results.
     */
    _computeReportURL(response) {

      if (this.zuulTenant) {
        // Zuul v3 live streaming URL has to be checked early because `report_url` always contains at least a placeholder
        if (response && response.result == null && response.url && response.url.startsWith('stream/')) {
          return `${this.zuulUrl}/t/${this.zuulTenant}/${response.url}`;
        }
      }

      if (response && response.report_url) {
        return response.report_url;
      }

      return '';
    },

    _progressPercent(jobs) {
      if (!jobs || !jobs.elapsed_time && !jobs.remaining_time) {
          return '';
      }

      let progressPercent = 100 * (jobs.elapsed_time / (jobs.elapsed_time +
          jobs.remaining_time));

      this.customStyle['--progress-bar-width'] = `${progressPercent}%;`;
      this.updateStyles();

      return progressPercent;
    },

    _getResults(jobs, equals, name) {
      let result = jobs.result ? jobs.result.toLowerCase() : null;
      if (result === null) {
        if (jobs.url === null) {
          result = 'queued'
        } else if (jobs.paused !== null && jobs.paused) {
          result = 'paused'
        } else {
          result = 'in progress'
        }
      }

      if (equals) {
        return result === name;
      } else {
        return result;
      }
    },

    _renderJobStatusLabel (jobs) {
      let result = jobs.result ? jobs.result.toLowerCase() : null;

      let className;

      switch (result) {
        case 'success':
          className = 'label-success'
          break;
        case 'failure':
          className = 'label-danger'
          break;
        case 'unstable':
          className = 'label-warning'
          break;
        case 'skipped':
          className = 'label-info'
          break;
        // 'in progress' 'queued' 'lost' 'aborted' ...
        default:
          className = 'label-default'
      }

      return className;
    },

    _handleDisableZuulStatus(e) {
      this._storage.setItem('disable_zuul_status', 'yes');

      this.reload();
    },

    _handleEnableZuulStatus(e) {
      this._storage.removeItem('disable_zuul_status');

      this.reload();
    },

    _isFailing(results) {
      if (results && results.results &&
          results.results.failing_reasons.length !== 0) {
        return true;
      }

      return false;
    },

    _getTime(ms, words) {
      if (typeof (words) === 'undefined') {
        words = false;
      }
      let seconds = (+ms) / 1000;
      let minutes = Math.floor(seconds / 60);
      let hours = Math.floor(minutes / 60);
      seconds = Math.floor(seconds % 60);
      minutes = Math.floor(minutes % 60);
      let r = '';
      if (words) {
        if (hours) {
          r += hours + ' hr ';
        }
        r += minutes + ' min';
      } else {
        if (hours < 10) {
          r += '0';
        }
        r += hours + ':';
        if (minutes < 10) {
          r += '0';
        }
        r += minutes + ':';
        if (seconds < 10) {
          r += '0';
        }
        r += seconds;
      }

      return r;
    },

    _getRemainingTime(time) {
      return time === null ?
          'unknown' : this._getTime(time, true);
    },

    _getEnqueueTime(ms) {
      // Special format case for enqueue time to add style
      let now = Date.now();
      let delta = now - ms;

      return this._getTime(delta, true);
    },
  });
})();
