'use strict';

var version     = require('../package.json').version
var stats       = require('./stats')
var summary     = require('./summary')
var subsegments = require('./subsegments')
var tree        = require('./tree')
var costTree    = require('./cost_tree')
var eventLoop   = require('./event_loop_agg')
var tags        = require('./tags')
var summaryStats = require("./timing_stats")

// NOTE:  the enhance API call modifies the waterfall in place.
// it will chop up segments to account for sub calls and compute nest levels
module.exports = function enhance(waterfall, options){
  waterfall.enhancedVersion = version
  var traceJsMicros = 0
  var traceOperatingTime = 0
  if( waterfall.waterfalls ){
    waterfall.waterfalls.forEach(function handleWaterfall(w){
      w.fnSegs = w.segments.filter(function(d){ return d.type == 'fn'})
      w.waitSegs = w.segments.filter(function(d){return d.type == 'wait'})
      tree(w)
      subsegments(w)
      w.costTree = costTree(w, waterfall.functions)
      eventLoop(w, waterfall.functions)
      summary(w, options)
      w.costSummary = costTree.summary(w.costTree, waterfall.functions)
      summaryStats(w)
      traceJsMicros += (w.timing_stats.jsMicros * w.instance_count)
      traceOperatingTime += (w.timing_stats.totalMicros * w.instance_count)
    })
  }
  stats.aggregateStats(waterfall)
  tags.enhanceTransactions(waterfall)

  // Append aggregate summary timing info to the entire tracefile
  var traceWindow = 0
  if (waterfall.transactions) {
    traceWindow = (waterfall.transactions.end - waterfall.transactions.start) * 1000
  }
  else {
    // no transaction log, so we don't have a specific window timeframe
    traceWindow = traceOperatingTime
  }

  // These summary_stats are *AGGREGATE*
  if (waterfall.summary_stats == null) {
    waterfall.summary_stats = {}
  }
  waterfall.summary_stats.jsMicros = traceJsMicros
  waterfall.summary_stats.totalMicros = traceOperatingTime
  waterfall.summary_stats.windowMicros = traceWindow
  // FIXME(setogit) set ceiling to avioid >100% or negative numbers
  //     Real fix is to ensure waterfall stats are calculated correctly. 
  waterfall.summary_stats.percentBlocked = Math.min(99.99, (traceJsMicros / traceWindow)*100)
  waterfall.summary_stats.percentAsync = (100 - waterfall.summary_stats.percentBlocked)
  waterfall.summary_stats.percentOperating = Math.min(99.99, (traceOperatingTime / traceWindow)*100)
  waterfall.summary_stats.percentIdle = (100 - waterfall.summary_stats.percentOperating)

  return waterfall
}
