<!DOCTYPE html>
<!--
Copyright (c) 2015 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="/extras/importer/jszip.html">
<link rel="import" href="/model/model.html">
<link rel="import" href="/importer/importer.html">

<script>
/**
 * @fileoverview Blah.
 */
'use strict';

tr.exportTo('tr.e.importer.ddms', function() {
  var Importer = tr.importer.Importer;

  var kPid = 0;
  var kCategory = 'java';
  var kMethodLutEndMarker = '\n*end\n';
  var kThreadsStart = '\n*threads\n';
  var kMethodsStart = '\n*methods\n';

  var kTraceMethodEnter = 0x00;       // method entry
  var kTraceMethodExit = 0x01;        // method exit
  var kTraceUnroll = 0x02;            // method exited by exception unrolling
  // 0x03 currently unused
  var kTraceMethodActionMask = 0x03;  // two bits

  var kTraceHeaderLength = 32;
  var kTraceMagicValue = 0x574f4c53;
  var kTraceVersionSingleClock = 2;
  var kTraceVersionDualClock = 3;
  var kTraceRecordSizeSingleClock = 10;  // using v2
  var kTraceRecordSizeDualClock = 14;  // using v3 with two timestamps

  function Reader(string_payload) {
    this.position_ = 0;
    this.data_ = JSZip.utils.transformTo('uint8array', string_payload);
  }

  Reader.prototype = {
    __proto__: Object.prototype,

    uint8: function() {
      var result = this.data_[this.position_];
      this.position_ += 1;
      return result;
    },

    uint16: function() {
      var result = 0;
      result += this.uint8();
      result += this.uint8() << 8;
      return result;
    },

    uint32: function() {
      var result = 0;
      result += this.uint8();
      result += this.uint8() << 8;
      result += this.uint8() << 16;
      result += this.uint8() << 24;
      return result;
    },

    uint64: function() {
      // Javascript isn't able to manage 64-bit numeric values.
      var low = this.uint32();
      var high = this.uint32();
      var low_str = ('0000000' + low.toString(16)).substr(-8);
      var high_str = ('0000000' + high.toString(16)).substr(-8);
      var result = high_str + low_str;
      return result;
    },

    seekTo: function(position) {
      this.position_ = position;
    },

    hasMore: function() {
      return this.position_ < this.data_.length;
    }
  };

  /**
   * Imports DDMS method tracing events into a specified model.
   * @constructor
   */
  function DdmsImporter(model, data) {
    this.importPriority = 3;
    this.model_ = model;
    this.data_ = data;
  }

  /**
   * Guesses whether the provided events is from a DDMS method trace.
   * @return {boolean} True when events is a DDMS method trace.
   */
  DdmsImporter.canImport = function(data) {
    if (typeof(data) === 'string' || data instanceof String) {
      var header = data.slice(0, 1000);
      return header.startsWith('*version\n') &&
        header.indexOf('\nvm=') >= 0 &&
        header.indexOf(kThreadsStart) >= 0;
    }
    /* key bit */
    return false;
  };

  DdmsImporter.prototype = {
    __proto__: Importer.prototype,

    get model() {
      return this.model_;
    },

    /**
     * Imports the data in this.data_ into this.model_.
     */
    importEvents: function(isSecondaryImport) {
      var divider = this.data_.indexOf(kMethodLutEndMarker) +
          kMethodLutEndMarker.length;
      this.metadata_ = this.data_.slice(0, divider);
      this.methods_ = {};
      this.parseThreads();
      this.parseMethods();

      var traceReader = new Reader(this.data_.slice(divider));
      var magic = traceReader.uint32();
      if (magic != kTraceMagicValue) {
        throw Error('Failed to match magic value');
      }
      this.version_ = traceReader.uint16();
      if (this.version_ != kTraceVersionDualClock) {
        throw Error('Unknown version');
      }
      var dataOffest = traceReader.uint16();
      var startDateTime = traceReader.uint64();
      var recordSize = traceReader.uint16();

      traceReader.seekTo(dataOffest);

      while (traceReader.hasMore()) {
        this.parseTraceEntry(traceReader);
      }
    },

    parseTraceEntry: function(reader) {
      var tid = reader.uint16();
      var methodPacked = reader.uint32();
      var cpuSinceStart = reader.uint32();
      var wallClockSinceStart = reader.uint32();
      var method = methodPacked & ~kTraceMethodActionMask;
      var action = methodPacked & kTraceMethodActionMask;
      var thread = this.getTid(tid);
      method = this.getMethodName(method);
      if (action == kTraceMethodEnter) {
        thread.sliceGroup.beginSlice(kCategory, method, wallClockSinceStart,
            undefined, cpuSinceStart);
      } else if (thread.sliceGroup.openSliceCount) {
        thread.sliceGroup.endSlice(wallClockSinceStart, cpuSinceStart);
      }
    },

    parseThreads: function() {
      var threads = this.metadata_.slice(this.metadata_.indexOf(kThreadsStart) +
          kThreadsStart.length);
      threads = threads.slice(0, threads.indexOf('\n*'));
      threads = threads.split('\n');
      threads.forEach(this.parseThread.bind(this));
    },

    parseThread: function(thread_line) {
      var tid = thread_line.slice(0, thread_line.indexOf('\t'));
      var thread = this.getTid(parseInt(tid));
      thread.name = thread_line.slice(thread_line.indexOf('\t') + 1);
    },

    getTid: function(tid) {
      return this.model_.getOrCreateProcess(kPid)
        .getOrCreateThread(tid);
    },

    parseMethods: function() {
      var methods = this.metadata_.slice(this.metadata_.indexOf(kMethodsStart) +
          kMethodsStart.length);
      methods = methods.slice(0, methods.indexOf('\n*'));
      methods = methods.split('\n');
      methods.forEach(this.parseMethod.bind(this));
    },

    parseMethod: function(method_line) {
      var data = method_line.split('\t');
      var methodId = parseInt(data[0]);
      var methodName = data[1] + '.' + data[2] + data[3];
      this.addMethod(methodId, methodName);
    },

    addMethod: function(methodId, methodName) {
      this.methods_[methodId] = methodName;
    },

    getMethodName: function(methodId) {
      return this.methods_[methodId];
    }
  };

  // Register the DdmsImporter to the Importer.
  tr.importer.Importer.register(DdmsImporter);

  return {
    DdmsImporter: DdmsImporter
  };
});
</script>
