// 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:playArrow';
          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:pause';
          icon.color = 'red';
          icon.tooltip = 'Waiting';
          break;
        case 'DUPLICATE':
          icon.id = 'gr-icons:check';
          icon.color = 'green';
          icon.tooltip = 'Duplicate';
          break;
        case 'PASS':
          icon.id = 'gr-icons:check-circle';
          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;
    },
  });
})();
