// 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 Defs = {};
  /**
   * @typedef {{
   *  message: string,
   *  sub_tasks: Array<Defs.Task>,
   *  hint: ?string,
   *  name: string,
   *  status: string
   * }}
   */
  Defs.Task;

  Polymer({
    is: 'gr-task-plugin',
    properties: {
      change: {
        type: Object,
      },

      // @type {Array<Defs.Task>}
      _tasks: {
        type: Array,
        notify: true,
        value() { return []; },
      },

      _show_all: {
        type: String,
        notify: true,
        value: 'false',
      },

      _expand_all: {
        type: Boolean,
        notify: true,
        value: true,
      },

      _all_count: {
        type: Number,
        notify: true,
        value: 0,
      },

      _ready_count: {
        type: Number,
        notify: true,
        value: 0,
      },

      _fail_count: {
        type: Number,
        notify: true,
        value: 0,
      },
    },

    _is_show_all(show_all) {
      return show_all === 'true';
    },

    attached() {
      this._getTasks();
    },

    _getTasks() {
      const endpoint =
          `/changes/?q=change:${this.change._number}&--task--applicable`;

      return this.plugin.restApi().get(endpoint).then(response => {
        if (response && response.length === 1) {
          const cinfo = response[0];
          if (cinfo.plugins) {
            const taskPluginInfo = cinfo.plugins.find(
                pluginInfo => pluginInfo.name === 'task');

            if (taskPluginInfo) {
              this._tasks = this._addTasks(taskPluginInfo.roots);
            }
          }
        }
      });
    },

    _computeIcon(task) {
      const icon = {};
      switch (task.status) {
        case 'FAIL':
          icon.id = 'gr-icons:close';
          icon.color = 'red';
          icon.tooltip = 'Failed';
          break;
        case 'READY':
          icon.id = 'gr-icons:rebase';
          icon.color = 'green';
          icon.tooltip = 'Ready';
          break;
        case 'INVALID':
          icon.id = 'gr-icons:abandon';
          icon.color = 'red';
          icon.tooltip = 'Invalid';
          break;
        case 'WAITING':
          icon.id = 'gr-icons:side-by-side';
          icon.color = 'red';
          icon.tooltip = 'Waiting';
          break;
        case 'PASS':
          icon.id = 'gr-icons:check';
          icon.color = 'green';
          icon.tooltip = 'Passed';
          break;
      }
      return icon;
    },

    _computeShowOnNeedsAndBlockedFilter(task) {
      switch (task.status) {
        case 'FAIL':
        case 'READY':
        case 'INVALID':
          return true;
      }
      return false;
    },

    _compute_counts(task) {
      this._all_count++;
      switch (task.status) {
        case 'FAIL':
          this._fail_count++;
          break;
        case 'READY':
          this._ready_count++;
          break;
      }
    },

    _addTasks(tasks) { // rename to process, remove DOM bits
      if (!tasks) return [];
      tasks.forEach(task => {
        task.message = task.hint || task.name;
        task.icon = this._computeIcon(task);
        task.showOnFilter = this._computeShowOnNeedsAndBlockedFilter(task);
        this._compute_counts(task);
        this._addTasks(task.sub_tasks);
      });
      return tasks;
    },

    _show_all_tap() {
      this._show_all = 'true';
      this._expand_all = true;
    },

    _needs_and_blocked_tap() {
      this._show_all = 'false';
      this._expand_all = true;
    },

    _switch_expand() {
      this._expand_all = !this._expand_all;
    },
  });
})();
