<!DOCTYPE html>
<!--
Copyright 2016 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->

<link rel="import" href="/components/core-icon-button/core-icon-button.html">
<link rel="import" href="/components/paper-button/paper-button.html">
<link rel="import" href="/components/paper-progress/paper-progress.html">

<link rel="import" href="/dashboard/elements/autocomplete-box.html">
<link rel="import" href="/dashboard/static/simple_xhr.html">
<link rel="import" href="/dashboard/static/testselection.html">

<polymer-element name="test-picker" attributes="hasChart xsrfToken testSuites">
  <template>
    <style>
      #container * {
        margin-right: 3px;
      }

      #dnd-btn {
        padding: 1px 2px;
        margin: 2px 4px 2px 2px;
        font-size: 11px;
        cursor:grabbing;
        cursor:-moz-grabbing;
        cursor:-webkit-grabbing;
      }

      paper-button {
        height: 35px;
      }

      paper-button:not([disabled]) {
        color: #4285f4;
      }

      paper-button[raised]:not([disabled]) {
        background: #4285f4;
        color: #fff;
      }

      core-icon {
        height: 25px;
      }

      #suite-description {
        padding: 10px;
      }

      #loading {
        display: block;
        position: relative;
        width: 152px;
        height: 35px;
      }

      paper-progress {
        display: block;
        position: absolute;
        bottom: -1px;
        height: 1px;
        width: 100%;
      }
    </style>

    <div id="container" horizontal layout center wrap>
      <template repeat="{{box, index in selectionModels}}">
        <autocomplete-box datalist={{box.datalist}}
                          placeholder="{{box.placeholder}}"
                          disabled={{box.disabled}}
                          multi={{box.multi}}
                          on-dropdownselect="{{onDropdownSelect}}"
                          id="selection-{{index}}"></autocomplete-box>
      </template>

      <template if="{{loading}}">
        <div id="loading">
          <paper-progress indeterminate></paper-progress>
        </div>
      </template>

      <core-icon-button id="dnd-btn"
                        icon="open-with"
                        disabled?="{{!enableAddSeries || !hasChart}}"
                        draggable="{{enableAddSeries && hasChart}}"
                        on-dragstart="{{onSeriesButtonDragStart}}">
        Drag me
      </core-icon-button>

      <paper-button raised
                    id="add-graph-btn"
                    on-click="{{onAddButtonClicked}}"
                    disabled?="{{!enableAddSeries}}">Add</paper-button>
    </div>

    <div id="suite-description"></div>
  </template>

  <script>
    'use strict';

    Polymer('test-picker', {

      TESTSUITE_LABEL: 'Test suite',
      BOT_LABEL: 'Bot',
      SUBTEST_LABEL: 'Subtest',
      DEPRECATED_TAG: 'no new data',
      UNMONITORED_TAG: 'unmonitored',

      ready: function() {
        this.pageStateLoading = true;
        this.hasChart = false;
        this.enableAddSeries = false;
        this.selectedSuite = null;
        this.suiteDescription = null;
        this.selectionModels = [
          {
            placeholder: this.TESTSUITE_LABEL,
            datalist: this.getSuiteItems()
          },
          {
            placeholder: this.BOT_LABEL,
            disabled: true,
            multi: true
          }
        ];
      },

      testSuitesChanged: function() {
        this.selectionModels[0].datalist = this.getSuiteItems();
        this.getSelectionMenu(0).setDataList(this.selectionModels[0].datalist);
      },

      /**
       * Gets a list of menu items for test suites.
       */
      getSuiteItems: function() {
        var suiteMenuItems = [];
        var self = this;
        var isUnmonitored = function(suite) {
          // A suite is considered unmonitored if there are no monitored
          // subtests.
          var suiteInfo = self.testSuites[suite];
          return !suiteInfo['mon'] || suiteInfo['mon'].length == 0;
        };

        for (var suite in this.testSuites) {
          var suiteItem = {
            name: suite
          };

          var tags = [];
          if (this.testSuites[suite]['dep']) {
            suiteItem.deprecated = true;
            tags.push(this.DEPRECATED_TAG);
          }
          if (isUnmonitored(suite)) {
            suiteItem.unmonitored = true;
            tags.push(this.UNMONITORED_TAG);
          }
          suiteItem.tag = tags.join(' ');

          suiteMenuItems.push(suiteItem);
        }
        suiteMenuItems.sort(this.compareTestSuiteItem);
        return suiteMenuItems;
      },

      /**
       * Gets a list of bot menu items base on the selected test suite.
       */
      getBotItems: function() {
        var suite = this.getSelectionMenu(0).value;
        if (!this.testSuites[suite]) {
          return [];
        }
        var dict = this.testSuites[suite]['mas'];
        var botMenuItems = [];
        var masters = Object.keys(dict).sort();
        for (var i = 0; i < masters.length; i++) {
          var groupItem = {
            name: masters[i],
            suite: suite,
            head: true
          };
          botMenuItems.push(groupItem);
          var bots = dict[masters[i]];
          var botNames = Object.keys(dict[masters[i]]).sort();
          for (var j = 0; j < botNames.length; j++) {
            var name = botNames[j];
            var botItem = {
              name: name,
              group: masters[i],
              tag: (bots[name] ? this.DEPRECATED_TAG : '')
            };
            botMenuItems.push(botItem);
          }
        }
        return botMenuItems;
      },

      /**
       * Handles dropdown menu select; updates the subsequent menu accordingly.
       */
      onDropdownSelect: function(event) {
        var model = event.target.templateInstance.model;
        var boxIndex = model.index;
        if (boxIndex == 0) {
          this.updateTestSuiteDescription();
          this.updateBotMenu();
        } else if (boxIndex == 1) {
          this.sendSubtestRequest();
        } else {
          // Update all the next dropdown menus for subtests.
          this.updateSubtestMenus(boxIndex + 1);
        }
      },

      updateTestSuiteDescription: function() {
        // Display the test suite description if there is one.
        var descriptionElement = this.$['suite-description'];
        var suite = this.getSelectionMenu(0).value;
        if (!suite || !this.testSuites[suite]) {
          descriptionElement.innerHTML = '';
          return;
        }

        var description = this.testSuites[suite]['des'];
        if (description) {
          var descriptionHTML = '<b>' + suite + '</b>: ';
          descriptionHTML += this.convertMarkdownLinks(description);
          descriptionElement.innerHTML = descriptionHTML;
        } else {
          descriptionElement.innerHTML = '';
        }
      },

      /**
       * Updates bot dropdown menu with bot items.
       */
      updateBotMenu: function() {
        var menu = this.getSelectionMenu(1);
        var botItems = this.getBotItems();
        menu.setDataList(botItems);
        menu.disabled = false;
        this.subtestDict = null;
        // If there's a selection, send a subtest request.
        if (menu.value && menu.value.length > 0) {
          this.sendSubtestRequest();
        } else {
          // Clear all subtest menus.
          this.selectionModels.splice(2);
        }
        this.updateAddButtonState();
      },

      /**
       * Sends a request for subtestDict base on selected test suite and bots.
       */
      sendSubtestRequest: function() {
        if (this.subtestXhr) {
          this.subtestXhr.abort();
          this.subtestXhr = null;
        }
        var bots = this.getCheckedBots();
        // If no bots are selected, just leave the current subtests.
        if (bots.length == 0) {
          return;
        }
        var suite = this.getCheckedSuite();
        if (!suite) {
          return;
        }

        this.loading = true;

        var params = {
          type: 'sub_tests',
          suite: suite,
          bots: bots.join(','),
          xsrf_token: this.xsrfToken
        };
        this.subtestXhr = simple_xhr.send(
            '/list_tests',
            params,
            function(response) {
              this.loading = false;
              this.subtestDict = response;
              // Start at first subtest menu.
              this.updateSubtestMenus(2);
            }.bind(this),
            function(error) {
              if (error) {
                console.log('Error from sendSubtestRequest.');
              }
              this.loading = false;
            }.bind(this)
        );
      },

      /**
       * Updates all subtest menus starting at 'startIndex'.
       */
      updateSubtestMenus: function(startIndex) {
        var subtestDict = this.getSubtestAtIndex(startIndex);

        // Update existing subtest menu.
        for (var i = startIndex; i < this.selectionModels.length; i++) {
          // Remove the rest of the menu if no subtestDict.
          if (!subtestDict || Object.keys(subtestDict).length == 0) {
            this.selectionModels.splice(i);
            this.updateAddButtonState();
            return;
          }
          var subtestItems = this.getSubtestItems(subtestDict);
          var menu = this.getSelectionMenu(i);
          menu.setDataList(subtestItems);

          // If there are selected item, update next menu.
          if (menu.value && menu.value.length > 0) {
            subtestDict = subtestDict[menu.value]['sub_tests'];
          } else {
            subtestDict = null;
          }
        }

        // Check if we still need to add a subtest menu.
        if (subtestDict && Object.keys(subtestDict).length > 0) {
          var subtestItems = this.getSubtestItems(subtestDict);
          this.selectionModels.push({
            placeholder: this.SUBTEST_LABEL,
            datalist: subtestItems
          });
        }

        this.updateAddButtonState();
      },

      updateAddButtonState: function() {
        var selection = this.getCurrentSelection();
        this.enableAddSeries = selection != null && selection.isValid();
      },

      getSubtestAtIndex: function(index) {
        var subtestDict = this.subtestDict;
        for (var i = 2; i < index; i++) {
          var test = this.getSelectionMenu(i).value;
          if (test in subtestDict) {
            subtestDict = subtestDict[test]['sub_tests'];
          } else {
            return null;
          }
        }
        return subtestDict;
      },

      getSubtestItems: function(subtestDict) {
        var subtestItems = [];
        var subtestNames = Object.keys(subtestDict).sort();
        for (var i = 0; i < subtestNames.length; i++) {
          var name = subtestNames[i];
          subtestItems.push({
            name: name,
            tag: (subtestDict[name]['deprecated'] ? this.DEPRECATED_TAG : '')
          });
        }
        return subtestItems;
      },

      getCheckedBots: function() {
        var bots = [];
        var botMenu = this.getSelectionMenu(1);
        var botItems = botMenu.getSelectedItems();
        for (var i = 0; i < botItems.length; i++) {
          bots.push(botItems[i]['group'] + '/' + botItems[i]['name']);
        }
        return bots;
      },

      getCheckedSuite: function() {
        var suiteMenu = this.getSelectionMenu(0);
        return suiteMenu.value;
      },

      getSelectionMenu: function(index) {
        return this.$.container.querySelector('#selection-' + index);
      },

      /**
       * Handler for drag start event for series drag button.
       */
      onSeriesButtonDragStart: function(event, detail, sender) {
        var selection = this.getCurrentSelection();
        var testPathAndSelected = selection.getTestPathAndSelectedSeries();
        event.dataTransfer.setData('type', 'seriesdnd');
        event.dataTransfer.setData(
            'data', JSON.stringify(testPathAndSelected));
        event.dataTransfer.effectAllowed = 'copy';
      },

      /**
       * Fires add event on 'Add' button clicked.
       */
      onAddButtonClicked: function(event, detail, sender) {
        this.fire('add');
      },

      /**
       * Gets the current selection from the menus. Returns null unless there
       * are valid test selection.
       */
      getCurrentSelection: function() {
        // Up to subtest menu.
        for (var i = 0; i < 3; i++) {
          var menu = this.getSelectionMenu(i);
          if (!menu || menu.getSelectedItems().length == 0) {
            return null;
          }
        }

        var suite = this.getSelectionMenu(0).getSelectedItems()[0];
        var selection = new testselection.TestSelection(this.testSuites);
        var testPathAndSelected = this.addTestPathFromSubtestDict(
            this.subtestDict, suite.name, 2);
        var bots = this.getCheckedBots();
        for (var i = 0; i < bots.length; i++) {
          for (var j = 0; j < testPathAndSelected.length; j++) {
            var fullTestPath = bots[i] + '/' + testPathAndSelected[j][0];
            selection.addTestPath(fullTestPath, testPathAndSelected[j][1]);
          }
        }

        return selection;
      },

      /**
       * This method recursively add test path from a subtestDict.  Selected
       * series are added at the last level of the menu.
       * @return {Array} List of pair of test path to list of selected series
       *     name.
       */
      addTestPathFromSubtestDict: function(subtestDict, testPath, level) {
        if (!subtestDict) {
          return [];
        }
        var testPathAndSelected = [];
        var nextMenu = this.getSelectionMenu(level + 1);
        // If this is the last menu with selection.
        var isLastLevel = (level == this.selectionModels.length - 1 ||
                           !nextMenu ||
                           nextMenu.getSelectedItems().length == 0);

        var items = this.getSelectionMenu(level).getSelectedItems();
        for (var i = 0; i < items.length; i++) {
          var name = items[i].name;
          var nextTestPath = testPath + '/' + name;
          var selectedSeries = [];
          if (isLastLevel) {
            if (subtestDict[name]['has_rows']) {
              selectedSeries.push(name);
            }
            // Select important traces by default.
            var nextSubtestDict = subtestDict[name]['sub_tests'];
            for (var subName in nextSubtestDict) {
              if (nextSubtestDict[subName]['has_rows'] &&
                  testselection.isImportant(nextTestPath + '/' + subName)) {
                selectedSeries.push(subName);
              }
            }
            testPathAndSelected.push([nextTestPath, selectedSeries]);
          } else {
            var results = this.addTestPathFromSubtestDict(
                subtestDict[name]['sub_tests'], nextTestPath, level + 1);
            testPathAndSelected.push.apply(testPathAndSelected, results);
          }
        }
        return testPathAndSelected;
      },

      /**
       * Sorts by suite items by deprecated, monitored and then by name.
       * @return {number} negative if suiteA should be before suiteB,
       *     positive if suiteA should be after suiteB, zero if they're equal.
       */
      compareTestSuiteItem: function(suiteA, suiteB) {
        if (!suiteA.deprecated && suiteB.deprecated) {
          return -1;
        }
        if (!suiteB.deprecated && suiteA.deprecated) {
          return 1;
        }
        if (!suiteA.unmonitored && suiteB.unmonitored) {
          return -1;
        }
        if (!suiteB.unmonitored && suiteA.unmonitored) {
          return 1;
        }
        var nameALower = suiteA.name.toLowerCase();
        var nameBLower = suiteB.name.toLowerCase();
        if (nameALower > nameBLower) {
          return 1;
        }
        if (nameALower < nameBLower) {
          return -1;
        }
        return 0;
      },

      /**
       * Converts a link in markdown format to a HTML link (anchor elements).
       * @param {string} text A link in markdown format.
       * @return {string} A hyperlink string.
       */
      convertMarkdownLinks: function(text) {
        return text.replace(/\[(.+?)\]\((.+?)\)/g, '<a href="$2">$1</a>');
      }
    });
  </script>
</polymer-element>
