// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// See also timeline_message_handler.js.

var traceObject;
var pendingRequests;
var loadingOverlay;

function onModelLoaded(model) {
  viewer.globalMode = true;
  viewer.model = model;
}

function clearTimeline() {
  viewer.model = undefined;
}

function onImportFail(err) {
  var overlay = new tr.ui.b.Overlay();
  overlay.textContent = tr.b.normalizeException(err).message;
  overlay.title = 'Import error';
  overlay.visible = true;
  console.log('import failed');
}

function compareTimestamp(a, b) { return a.ts - b.ts; }
function compareBeginTimestamp(a, b) { return a.begin.ts - b.begin.ts; }
function compareEndTimestamp(a, b) { return a.end.ts - b.end.ts; }

var basicModelEventsWaterfall = [
  // Sort events and remove orphan async ends.
  function filterUnwantedEvents(events) {
    events = events.slice();
    events.sort(compareTimestamp);
    var threads = {};
    return events.filter(function (event) {
      if (event.ph === 'E') {
        return threads[event.tid] && threads[event.tid].pop();
      }
      var result = event.args && event.args.mode === 'basic';
      if (event.ph === 'B') {
        threads[event.tid] = threads[event.tid] || [];
        threads[event.tid].push(result);
      }
      return result;
    });
  }
];

var frameModelEventsWaterfall = [
  // Sort events and remove orphan async ends.
  function filterUnwantedEvents(events) {
    events = events.slice();
    events.sort(compareTimestamp);
    var threads = {};
    return events.filter(function (event) {
      if (event.ph === 'E') {
        if (!threads[event.tid]) {
          return false
        }
        threads[event.tid] -= 1;
      } else if (event.ph === 'B') {
        threads[event.tid] = (threads[event.tid] || 0) + 1;
      }
      return true;
    });
  },
  // Clone the events (we want to preserve them for dumps).
  function cloneDeep(input) {
    if (typeof input === 'object') {
      if (Array.isArray(input)) {
        return input.map(cloneDeep);
      } else {
        var clone = {};
        Object.keys(input).forEach(function (key) {
          clone[key] = cloneDeep(input[key]);
        });
        return clone;
      }
    }
    return input;
  },
  // Group nested sync begin end sequences on every thread.
  //
  // Example:
  // Input = [B,B,E,B,E,E,B,E,B,B,E,E]
  // Output = [[B,B,E,B,E,E],[B,E],[B,B,E,E]]
  function groupIsolatedPerThreadSequences(events) {
    var sequences = [],
      timeless = [],
      threadOpen = {};
      threadSequences = {};
    events.forEach(function (event) {
      if (event.ph === 'M') {
        timeless.push(event);
      } else if (event.ph === 'B') {
        threadOpen[event.tid] = Math.max(threadOpen[event.tid] || 0) + 1;
        threadSequences[event.tid] = threadSequences[event.tid] || [];
        threadSequences[event.tid].push(event);
      } else if (event.ph === 'E') {
        threadSequences[event.tid].push(event);
        threadOpen[event.tid] -= 1;
        if (threadOpen[event.tid] == 0) {
          threadSequences[event.tid].sort()
          sequences.push(threadSequences[event.tid]);
          threadSequences[event.tid] = [];
        }
      } else if (threadSequences[event.tid]){
        threadSequences[event.tid] = threadSequences[event.tid] || [];
        threadSequences[event.tid].push(event);
      }
    })
    return {
      timeless: timeless,
      sequences: sequences
    };
  },
  // Transform every sequence into an object for rapid begin end analysis and
  // block types lookup.
  //
  // Example:
  // Input = [B1,B2,E2,B3,E3,E1]
  // Output = {
  //   begin: B1,
  //   end: E1,
  //   events: [B1,B2,E2,B3,E3,E1],
  //   isGPU: ...,
  //   isVSync: ...,
  //   isFramework: ...,
  //   isShiftable: ...,
  // }
  function sequenceToBlockDescriptor(input) {
    return {
      timeless: input.timeless,
      blocks: input.sequences.map(function (events) {
        var begin,
            end,
            isGPU,
            isVSync,
            isFramework;
        events.forEach(function (event) {
          if (event.ph === 'B') {
            begin = begin || event;
          } else if (event.ph === 'E') {
            end = event;
          }
        });
        isGPU = begin.name === 'GPU Workload';
        isVSync = begin.name === 'VSYNC';
        isFramework = begin.name === 'Framework Workload';
        return {
          begin: begin,
          end: end,
          events: events,
          isGPU: isGPU,
          isVSync: isVSync,
          isFramework: isFramework,
          isShiftable: !(isGPU || isVSync || isFramework)
        };
      })
    };
  },
  // Remove all the blocks that ended before the first VSYNC.
  // These events do not give any information to the analysis.
  function removePreVSyncBlocks(input) {
    input.blocks.sort(compareEndTimestamp);
    var sawVSyncBlock = false;
    return {
      timeless: input.timeless,
      blocks: input.blocks.filter(function (block) {
        sawVSyncBlock = sawVSyncBlock || block.isVSync;
        return sawVSyncBlock;
      })
    };
  },
  // Remove all the GPU blocks that started before the first Framework block.
  // They are orphans of other frames.
  function removePreFrameworkGPUBlocks(input) {
    input.blocks.sort(compareBeginTimestamp);
    var firstFrameworkBlockBeginTimestamp = 0;
    return {
      timeless: input.timeless,
      blocks: input.blocks.filter(function (block) {
        if (block.isFramework) {
          firstFrameworkBlockBeginTimestamp =
              firstFrameworkBlockBeginTimestamp || block.begin.ts;
        } else if (block.isGPU) {
          if (!firstFrameworkBlockBeginTimestamp) {
            return false;
          } else if (block.begin.ts < firstFrameworkBlockBeginTimestamp) {
            return false;
          }
        }
        return true;
      })
    };
  },
  // Merge all shiftable blocks that are between two Framework blocks.
  // By merging them we preserve their relative timing.
  function mergeShiftableBlocks(input) {
    input.blocks.sort(compareEndTimestamp);
    var begin,
        end,
        events = [],
        shiftableBlocks = [],
        blocks;
    blocks = input.blocks.filter(function (block) {
      if (block.isShiftable) {
        begin = begin || block.begin;
        end = block.end;
        events = events.concat(block.events);
        return false;
      } else if (block.isFramework) {
        if (events.length) {
          shiftableBlocks.push({
            begin: begin,
            end: end,
            events: events
          });
        }
      }
      return true;
    });
    if (events.length) {
      shiftableBlocks.push({
        begin: begin,
        end: end,
        events: events
      });
    }
    return {
      timeless: input.timeless,
      blocks: blocks.concat(shiftableBlocks)
    };
  },
  // Remove all VSyncs that didn't started an actual frame.
  function filterFramelessVSyncs(input) {
    input.blocks.sort(compareBeginTimestamp);
    var lastVSyncBlock,
      blocks,
      vSyncBlocks = [];
    blocks = input.blocks.filter(function (block) {
      if (block.isVSync) {
        lastVSyncBlock = block;
        return false;
      } else if (block.isFramework) {
        vSyncBlocks.push(lastVSyncBlock);
      }
      return true;
    });
    return {
      timeless: input.timeless,
      blocks: blocks.concat(vSyncBlocks)
    };
  },
  // Group blocks by type.
  //
  // Example:
  // Input = [S1, V1, F1, V2, G1, F2, V3, G2, F3]
  // Output = {
  //   gpu: [G1, G2],
  //   vsync: [V1, V2, V3],
  //   framework: [F1, F2, F3],
  //   shiftable: [S1]
  // }
  function groupBlocksByFrames(input) {
    return {
      timeless: input.timeless,
      gpu: input.blocks.filter(function (b) { return b.isGPU; }),
      vsync: input.blocks.filter(function (b) { return b.isVSync; }),
      framework: input.blocks.filter(function (b) { return b.isFramework; }),
      shiftable: input.blocks.filter(function (b) { return b.isShiftable; })
    };
  },
  // Remove possible out of sync GPU Blocks.
  // If the buffer has already delete the VSync and the Framework, but not the
  // GPU it can potentially be still alive.
  function groupBlocksByFrames(input) {
    var gpu = input.gpu,
        framework = input.framework;
    while (gpu.length &&
           gpu[0].begin.args.frame !== framework[0].begin.args.frame) {
      gpu.shift();
    }
    return input;
  },
  // Group blocks related to the same frame.
  // Input = {
  //   gpu: [G1, G2],
  //   vsync: [V1, V2],
  //   framework: [F1, F2],
  //   shiftable: [S1]
  // }
  // Output = [{V1, F1, G1, S1}, {V2, F2, G2}, {V3, F3, G3}]
  function groupBlocksByFrames(input) {
    var shiftable = input.shiftable.slice();
    return {
      timeless: input.timeless,
      frames: input.vsync.map(function (vsync, i) {
        var frame = {
          begin: vsync.begin,
          vsync: vsync,
          framework: input.framework[i],
          deadline: parseInt(vsync.begin.args.deadline) + 1000
        };
        if (i < input.gpu.length) {
          frame.gpu = input.gpu[i];
        }
        if (shiftable.length && shiftable[0].begin.ts < framework.begin.ts ) {
          frame.shiftable = shiftable.shift();
        }
        return frame;
      })
    };
  },
  // Move Framework and GPU as back in time as possible
  //
  // Example:
  // Before
  //                               [GPU]
  //     [VSYNC]
  //  [SHIFTABLE]     [FRAMEWORK]
  // After
  //             |[GPU]
  //     [VSYNC] |
  //  [SHIFTABLE]|[FRAMEWORK]
  function shiftEvents(input) {
    input.frames.forEach(function (frame) {
      var earlierTimestamp = frame.vsync.end.ts,
          shift;
      if (frame.shiftable) {
        frame.shiftable.events.forEach(function (event) {
          if (event.tid === frame.framework.begin.tid) {
            earlierTimestamp = Math.max(earlierTimestamp, event.ts);
          }
        });
      }
      if (frame.gpu) {
        if (frame.shiftable) {
          frame.shiftable.events.forEach(function (event) {
            if (event.tid === frame.gpu.begin.tid) {
              earlierTimestamp = Math.max(earlierTimestamp, event.ts);
            }
          });
        }
        shift = earlierTimestamp - frame.gpu.begin.ts;
        frame.gpu.events.forEach(function (event) {
          event.ts += shift;
        });
      }
      shift = earlierTimestamp - frame.framework.begin.ts;
      frame.framework.events.forEach(function (event) {
        event.ts += shift;
      });
      frame.end = frame.framework.end;
      if (frame.gpu && frame.framework.end.ts < frame.gpu.end.ts) {
        frame.end = frame.gpu.end;
      }
    });
    return input;
  },
  // Group events in frame (precomputation for next stage).
  function groupEventsInFrame(input) {
    input.frames.forEach(function (frame) {
      var events = frame.vsync.events;
      events = events.concat(frame.framework.events);
      if (frame.gpu) {
        events = events.concat(frame.gpu.events);
      }
      if (frame.shiftable) {
        events = events.concat(frame.shiftable.events);
      }
      events.sort(compareTimestamp);
      frame.events = events;
    });
    return input;
  },
  // Move frames in order to do not overlap.
  //
  // Example:
  // Before
  //              |[GPU1--------------------]
  //                                     |[GPU2----]
  //     [VSYNC1] |             [VSYNC2] |
  //  [SHIFTABLE1]|[FRAMEWORK1]          |[FRAMEWORK2]
  // After
  //              |[GPU1--------------------]|         |[GPU2-----]
  //     [VSYNC1] |                          |[VSYNC2] |
  //  [SHIFTABLE1]|[FRAMEWORK1]              |         |[FRAMEWORK2]
  // OtherExample:
  // Before
  //     {FRAME BUDGET1-------------------------}
  //                            {FRAME BUDGET2-------------------------}
  //              |[GPU1]
  //                                     |[GPU2]
  //     [VSYNC1] |             [VSYNC2] |
  //  [SHIFTABLE1]|[FRAMEWORK1]          |[FRAMEWORK2]
  // After
  //     {FRAME BUDGET1-------------------------}|{FRAME BUDGET2----------------
  //              |[GPU1]                        |         |[GPU2-----]
  //     [VSYNC1] |                              |[VSYNC2] |
  //  [SHIFTABLE1]|[FRAMEWORK1]                  |         |[FRAMEWORK2]
  function shiftBlocks(input) {
    function minThreadtimestamps(frame) {
      var timestamps = {};
      frame.events.forEach(function (event) {
        if (event.tid != undefined) {
          timestamps[event.tid] = timestamps[event.tid] || event.ts;
        }
      });
      return timestamps;
    }
    function maxThreadTimestamps(frame) {
      var timestamps = {};
      frame.events.forEach(function (event) {
        if (event.tid != undefined) {
          timestamps[event.tid] = event.ts;
        }
      });
      return timestamps;
    }
    input.frames.slice(1).forEach(function (current, index) {
      var previous = input.frames[index],
        shift = Math.max(previous.end.ts, previous.deadline) - current.begin.ts,
        maxThreadTimestamp = maxThreadTimestamps(previous),
        minThreadTimestamp = minThreadtimestamps(current);
      Object.keys(maxThreadTimestamp).forEach(function (tid) {
        if (minThreadTimestamp[tid]) {
          var delta = maxThreadTimestamp[tid] - minThreadTimestamp[tid];
          shift = Math.max(shift, delta);
        }
      });
      current.events.forEach(function (event) {
        event.ts += shift;
      });
      current.deadline += shift;
    });
    return input;
  },
  // Add auxilary events to frame (Frame Budget and Frame Length).
  // Example:
  // Before
  //              |[GPU1--------------------]|         |[GPU2-----]
  //     [VSYNC1] |                          |[VSYNC2] |
  //  [SHIFTABLE1]|[FRAMEWORK1]              |         |[FRAMEWORK2]
  // After
  //     [Budget1---------------------------]|[Budget2--------------------------
  //     [Length1---------------------------]|[Length2------------]
  //              |[GPU1--------------------]|         |[GPU2-----]
  //     [VSYNC1] |                          |[VSYNC2] |
  //  [SHIFTABLE1]|[FRAMEWORK1]              |         |[FRAMEWORK2]
  function addAuxilaryEvents(input) {
    input.frames.forEach(function (frame) {
      frame.events.unshift({
        args: {name: "Frame Budgets"},
        name: "thread_name",
        ph: "M",
        pid: frame.begin.pid,
        tid: "budgets",
      });
      frame.events.unshift({
        args: {name: "Frames"},
        name: "thread_name",
        ph: "M",
        pid: frame.begin.pid,
        tid: "frames",
      });
      var duration = Math.floor((frame.end.ts - frame.begin.ts) / 1000),
          frameName = "Frame " + duration + "ms";
      frame.events = frame.events.concat({
          ph: "B",
          name: "Frame Budget",
          cat: "budgets",
          pid: frame.begin.pid,
          tid: "budgets",
          ts: frame.begin.ts
        }, {
          ph: "E",
          name: "Frame Budget",
          cat: "budgets",
          pid: frame.begin.pid,
          tid: "budgets",
          ts: frame.deadline,
          cname: 'rail_response'
        }, {
          ph: "B",
          name: frameName,
          cat: "frames",
          pid: frame.begin.pid,
          tid: "frames",
          ts: frame.begin.ts
        }, {
          ph: "E",
          name: frameName,
          cat: "frames",
          pid: frame.begin.pid,
          tid: "frames",
          ts: frame.end.ts,
          cname: frame.end.ts > frame.deadline ? 'terrible' : 'good'
        });
    });
    return input;
  },
  // Restore the events array used by catapult.
  function linearizeBlocks(input) {
    return input.frames.reduce(function (events, frame) {
      return events.concat(frame.events);
    }, input.timeless);
  }
];

function basicModelEventsMap(events) {
  return basicModelEventsWaterfall.reduce(function (input, step) {
    return step(input);
  }, events);
}

function frameModelEventsMap(events) {
  return frameModelEventsWaterfall.reduce(function (input, step) {
    return step(input);
  }, events);
}

function updateTimeline(events) {
  if (window.location.hash.indexOf('mode=basic') > -1) {
    events = {
      'stackFrames': events['stackFrames'],
      'traceEvents': basicModelEventsMap(events['traceEvents'])
    };
  }
  if (window.location.hash.indexOf('view=frame') > -1) {
    events = {
      'stackFrames': events['stackFrames'],
      'traceEvents': frameModelEventsMap(events['traceEvents'])
    };
  }
  var model = new tr.Model();
  var importer = new tr.importer.Import(model);
  var p = importer.importTracesWithProgressDialog([events]);
  p.then(onModelLoaded.bind(undefined, model), onImportFail);
}

function fetchUri(uri, onLoad, onError) {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', uri, true);
  xhr.responseType = 'text';
  xhr.addEventListener('load', onLoad);
  xhr.addEventListener('error', onError);
  xhr.send();
  console.log('GET ' + uri);
}

function showLoadingOverlay(msg) {
  if (!loadingOverlay) {
    loadingOverlay = new tr.ui.b.Overlay();
  }
  loadingOverlay.textContent = msg;
  loadingOverlay.title = 'Loading...';
  loadingOverlay.visible = true;
}

function hideLoadingOverlay() {
  if (!loadingOverlay) {
    return;
  }
  loadingOverlay.visible = false;
  loadingOverlay = undefined;
}

function gotReponse() {
  pendingRequests--;
  if (pendingRequests === 0) {
    console.log('Got all timeline parts');
    updateTimeline(traceObject);
    hideLoadingOverlay();
  }
}

function processTimelineResponse(response) {
  if (response.error) {
    // Maybe profiling is disabled.
    console.log('ERROR ' + response.error.message);
  } else {
    var result = response['result'];
    var newStackFrames = result['stackFrames'];  // Map.
    var newTraceEvents = result['traceEvents'];  // List.

    // Merge in timeline events.
    traceObject.traceEvents = traceObject.traceEvents.concat(newTraceEvents);
    for (var key in newStackFrames) {
      if (newStackFrames.hasOwnProperty(key)) {
        traceObject.stackFrames[key] = newStackFrames[key];
      }
    }
  }

  gotReponse();
}

function fetchTimelineOnLoad(event) {
  var xhr = event.target;
  var response = JSON.parse(xhr.responseText);
  processTimelineResponse(response);
}

function fetchTimelineOnError(event) {
  var xhr = event.target;
  console.log(xhr.statusText);
  gotReponse();
}

function fetchCPUProfile(vmAddress, isolateIds, timeOrigin, timeExtent) {
  showLoadingOverlay('Fetching CPU profile(s) from Dart VM');
  var parser = document.createElement('a');
  parser.href = vmAddress;
  pendingRequests += isolateIds.length;
  for (var i = 0; i < isolateIds.length; i++) {
    var isolateId = isolateIds[i];
    var requestUri = 'http://' +
                     parser.hostname +
                     ':' +
                     parser.port +
                     '/_getCpuProfileTimeline?tags=None&isolateId=' +
                     isolateId +
                     '&timeOriginMicros=' + timeOrigin +
                     '&timeExtentMicros=' + timeExtent;
    fetchUri(requestUri, fetchTimelineOnLoad, fetchTimelineOnError);
  }
}

function fetchTimeline(vmAddress, isolateIds, mode) {
  // Reset combined timeline.
  traceObject = {
    'stackFrames': {},
    'traceEvents': []
  };
  timelineMode = mode;
  pendingRequests = 1;

  showLoadingOverlay('Fetching timeline from Dart VM');
  var parser = document.createElement('a');
  parser.href = vmAddress;
  var requestUri = 'http://' +
                   parser.hostname +
                   ':' +
                   parser.port +
                   '/_getVMTimeline';
  fetchUri(requestUri, function(event) {
    // Grab the response.
    var xhr = event.target;
    var response = JSON.parse(xhr.responseText);
    // Extract the time origin and extent.
    var timeOrigin = response['result']['timeOriginMicros'];
    var timeExtent = response['result']['timeExtentMicros'];
    console.assert(Number.isInteger(timeOrigin), timeOrigin);
    console.assert(Number.isInteger(timeExtent), timeExtent);
    console.log(timeOrigin);
    console.log(timeExtent);
    // fetchCPUProfile.
    fetchCPUProfile(vmAddress, isolateIds, timeOrigin, timeExtent);
    // This must happen after 'fetchCPUProfile';
    processTimelineResponse(response, mode);
  }, fetchTimelineOnError);
}

function saveTimeline() {
  if (pendingRequests > 0) {
    var overlay = new tr.ui.b.Overlay();
    overlay.textContent = 'Cannot save timeline while fetching one.';
    overlay.title = 'Save error';
    overlay.visible = true;
    console.log('cannot save timeline while fetching one.');
    return;
  }
  if (!traceObject ||
      !traceObject.traceEvents ||
      (traceObject.traceEvents.length === 0)) {
    var overlay = new tr.ui.b.Overlay();
    overlay.textContent = 'Cannot save an empty timeline.';
    overlay.title = 'Save error';
    overlay.visible = true;
    console.log('Cannot save an empty timeline.');
    return;
  }
  var blob = new Blob([JSON.stringify(traceObject)],
                      {type: 'application/json'});
  var blobUrl = URL.createObjectURL(blob);
  var link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
  link.href = blobUrl;
  var now = new Date();
  var defaultFilename = 'dart-timeline-' +
                        now.getFullYear() +
                        '-' +
                        now.getMonth() +
                        '-' +
                        now.getDate() +
                        '.json';
  var filename = window.prompt('Save as', defaultFilename);
  if (filename) {
    link.download = filename;
    link.click();
  }
}

function loadTimeline() {
  if (pendingRequests > 0) {
    var overlay = new tr.ui.b.Overlay();
    overlay.textContent = 'Cannot load timeline while fetching one.';
    overlay.title = 'Save error';
    overlay.visible = true;
    console.log('Cannot load timeline while fetching one.');
    return;
  }
  var inputElement = document.createElement('input');
  inputElement.type = 'file';
  inputElement.multiple = false;

  var changeFired = false;
  inputElement.addEventListener('change', function(e) {
    if (changeFired)
      return;
    changeFired = true;

    var file = inputElement.files[0];
    var reader = new FileReader();
    reader.onload = function(event) {
      try {
        traceObject = JSON.parse(event.target.result);
        updateTimeline(traceObject);
      } catch (error) {
        tr.ui.b.Overlay.showError('Error while loading file: ' + error);
      }
    };
    reader.onerror = function(event) {
      tr.ui.b.Overlay.showError('Error while loading file: ' + event);
    };
    reader.onabort = function(event) {
      tr.ui.b.Overlay.showError('Error while loading file: ' + event);
    }
    reader.readAsText(file);
  });
  inputElement.click();
}

function refreshTimeline() {
  updateTimeline(traceObject);
}

window.addEventListener('DOMContentLoaded', function() {
  var container = document.createElement('track-view-container');
  container.id = 'track_view_container';
  viewer = document.createElement('tr-ui-timeline-view');
  viewer.track_view_container = container;
  viewer.appendChild(container);
  viewer.id = 'trace-viewer';
  viewer.globalMode = true;
  document.body.appendChild(viewer);
  timeline_loaded = true;
  console.log('DOMContentLoaded');
  document.getElementById('trace-viewer').highlightVSync = true;
  if (timeline_vm_address != undefined) {
    console.log('Triggering delayed timeline refresh.');
    fetchTimeline(timeline_vm_address, timeline_isolates);
    timeline_vm_address = undefined;
    timeline_isolates = undefined;
  }
});

console.log('timeline.js loaded');
