/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

import Ember from 'ember';
import constants from 'hive/utils/constants';
import utils from 'hive/utils/functions';

export default Ember.ObjectController.extend({
  cachedExplains: [],

  clearCachedExplainSet: function (jobId) {
    var existingJob = this.get('cachedExplains').findBy('id', jobId);

    if (existingJob) {
      this.set('cachedExplains', this.get('cachedExplains').without(existingJob));
    }
  },

  initExplain: function () {
    var cachedExplain;

    cachedExplain = this.get('cachedExplains').findBy('id', this.get('content.id'));

    if (cachedExplain) {
      this.formatExplainResults(cachedExplain);
    } else {
      this.getExplain();
    }
  }.observes('content'),

  getExplain: function () {
    var self = this;
    var url = this.container.lookup('adapter:application').buildURL();
    url += '/' + constants.namingConventions.jobs + '/' + this.get('content.id') + '/results?first=true';

    Ember.$.getJSON(url).then(function (data) {
      var explainSet = self.get('cachedExplains').pushObject(Ember.Object.create({
        id: self.get('content.id'),
        explain: data
      }));

      self.set('content.explain', explainSet);

      self.formatExplainResults(explainSet);
    });
  },

  formatExplainResults: function (explainSet) {
    var formatted = [],
        orderedNodes = [],
        currentNode,
        currentNodeWhitespace,
        previousNode,
        formattedExplain = [],
        getLeadingWhitespacesCount = function (str) {
          return str.replace(utils.regexes.whitespaces, '$1').length;
        };

    explainSet = explainSet
                 .get('explain.rows')
                 .map(function (row) {
                    return row[0];
                  })
                 .filter(Boolean)
                 .map(function (str) {
                    return {
                      text: str,
                      parentNode: null,
                      contents: []
                    }
                  });

    for (var i = 0; i < explainSet.length; i++) {
      currentNode = explainSet[i];
      previousNode = explainSet[i-1];

      if (i > 0) {
        currentNodeWhitespace = getLeadingWhitespacesCount(currentNode.text);

        if (currentNodeWhitespace > getLeadingWhitespacesCount(previousNode.text)) {
          currentNode.parentNode = previousNode;
          previousNode.contents.pushObject(currentNode);
        } else {
          for (var j = i - 1; j >= 0; j--) {
            if (currentNodeWhitespace === getLeadingWhitespacesCount(explainSet[j].text)) {
              if (currentNodeWhitespace > 0) {
                currentNode.parentNode = explainSet[j].parentNode;
                currentNode.parentNode.contents.pushObject(currentNode);
              } else {
                formatted.pushObject(currentNode);
              }

              break;
            }
          }
        }
      } else {
        formatted.pushObject(currentNode);
      }
    }

    this.set('formattedExplain', formatted);
  }
});