#!/usr/bin/env python
#
# Copyright (C) 2014 The Android Open Source Project
#
# Licensed 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.

"""Script that parses a trace filed produced in streaming mode. The file is broken up into
   a header and body part, which, when concatenated, make up a non-streaming trace file that
   can be used with traceview."""

import sys

class MyException(Exception):
  pass

class BufferUnderrun(Exception):
  pass

def ReadShortLE(f):
  byte1 = f.read(1)
  if not byte1:
    raise BufferUnderrun()
  byte2 = f.read(1)
  if not byte2:
    raise BufferUnderrun()
  return ord(byte1) + (ord(byte2) << 8);

def WriteShortLE(f, val):
  bytes = [ (val & 0xFF), ((val >> 8) & 0xFF) ]
  asbytearray = bytearray(bytes)
  f.write(asbytearray)

def ReadIntLE(f):
  byte1 = f.read(1)
  if not byte1:
    raise BufferUnderrun()
  byte2 = f.read(1)
  if not byte2:
    raise BufferUnderrun()
  byte3 = f.read(1)
  if not byte3:
    raise BufferUnderrun()
  byte4 = f.read(1)
  if not byte4:
    raise BufferUnderrun()
  return ord(byte1) + (ord(byte2) << 8) + (ord(byte3) << 16) + (ord(byte4) << 24);

def WriteIntLE(f, val):
  bytes = [ (val & 0xFF), ((val >> 8) & 0xFF), ((val >> 16) & 0xFF), ((val >> 24) & 0xFF) ]
  asbytearray = bytearray(bytes)
  f.write(asbytearray)

def Copy(input, output, length):
  buf = input.read(length)
  if len(buf) != length:
    raise BufferUnderrun()
  output.write(buf)

class Rewriter:

  def PrintHeader(self, header):
    header.write('*version\n');
    header.write('3\n');
    header.write('data-file-overflow=false\n');
    header.write('clock=dual\n');
    header.write('vm=art\n');

  def ProcessDataHeader(self, input, body):
    magic = ReadIntLE(input)
    if magic != 0x574f4c53:
      raise MyException("Magic wrong")

    WriteIntLE(body, magic)

    version = ReadShortLE(input)
    if (version & 0xf0) != 0xf0:
      raise MyException("Does not seem to be a streaming trace: %d." % version)
    version = version ^ 0xf0

    if version != 3:
      raise MyException("Only support version 3")

    WriteShortLE(body, version)

    # read offset
    offsetToData = ReadShortLE(input) - 16
    WriteShortLE(body, offsetToData + 16)

    # copy startWhen
    Copy(input, body, 8)

    if version == 1:
      self._mRecordSize = 9;
    elif version == 2:
      self._mRecordSize = 10;
    else:
      self._mRecordSize = ReadShortLE(input)
      WriteShortLE(body, self._mRecordSize)
      offsetToData -= 2;

    # Skip over offsetToData bytes
    Copy(input, body, offsetToData)

  def ProcessMethod(self, input):
    stringLength = ReadShortLE(input)
    str = input.read(stringLength)
    self._methods.append(str)
    print 'New method: %s' % str

  def ProcessThread(self, input):
    tid = ReadShortLE(input)
    stringLength = ReadShortLE(input)
    str = input.read(stringLength)
    self._threads.append('%d\t%s\n' % (tid, str))
    print 'New thread: %d/%s' % (tid, str)

  def ProcessSpecial(self, input):
    code = ord(input.read(1))
    if code == 1:
      self.ProcessMethod(input)
    elif code == 2:
      self.ProcessThread(input)
    else:
      raise MyException("Unknown special!")

  def Process(self, input, body):
    try:
      while True:
        threadId = ReadShortLE(input)
        if threadId == 0:
          self.ProcessSpecial(input)
        else:
          # Regular package, just copy
          WriteShortLE(body, threadId)
          Copy(input, body, self._mRecordSize - 2)
    except BufferUnderrun:
      print 'Buffer underrun, file was probably truncated. Results should still be usable.'

  def Finalize(self, header):
    header.write('*threads\n')
    for t in self._threads:
      header.write(t)
    header.write('*methods\n')
    for m in self._methods:
      header.write(m)
    header.write('*end\n')

  def ProcessFile(self, filename):
    input = open(filename, 'rb')                     # Input file
    header = open(filename + '.header', 'w')         # Header part
    body = open(filename + '.body', 'wb')            # Body part

    self.PrintHeader(header)

    self.ProcessDataHeader(input, body)

    self._methods = []
    self._threads = []
    self.Process(input, body)

    self.Finalize(header)

    input.close()
    header.close()
    body.close()

def main():
  Rewriter().ProcessFile(sys.argv[1])
  header_name = sys.argv[1] + '.header'
  body_name = sys.argv[1] + '.body'
  print 'Results have been written to %s and %s.' % (header_name, body_name)
  print 'Concatenate the files to get a result usable with traceview.'
  sys.exit(0)

if __name__ == '__main__':
  main()