/**
 * @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) {
      if (!change || !revision) return [];

      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) {
      if (!change || !revision) return false;

      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);
    },
  });
})();
