# Copyright 2012 Google Inc. All Rights Reserved.
"""A script that symbolizes perf.data files."""
import optparse
import os
import shutil
from subprocess import call
from subprocess import PIPE
from subprocess import Popen
from utils import misc

GSUTIL_CMD = 'gsutil cp gs://chromeos-image-archive/%s-release/%s/debug.tgz %s'
TAR_CMD = 'tar -zxvf %s -C %s'
PERF_BINARY = '/google/data/ro/projects/perf/perf'
VMLINUX_FLAG = ' --vmlinux=/usr/lib/debug/boot/vmlinux'
PERF_CMD = PERF_BINARY + ' report -i %s -n --symfs=%s' + VMLINUX_FLAG


def main():
  parser = optparse.OptionParser()
  parser.add_option('--in', dest='in_dir')
  parser.add_option('--out', dest='out_dir')
  parser.add_option('--cache', dest='cache')
  (opts, _) = parser.parse_args()
  if not _ValidateOpts(opts):
    return 1
  else:
    for filename in os.listdir(opts.in_dir):
      try:
        _DownloadSymbols(filename, opts.cache)
        _PerfReport(filename, opts.in_dir, opts.out_dir, opts.cache)
      except:
        print 'Exception caught. Continuing...'
  return 0


def _ValidateOpts(opts):
  """Ensures all directories exist, before attempting to populate."""
  if not os.path.exists(opts.in_dir):
    print "Input directory doesn't exist."
    return False
  if not os.path.exists(opts.out_dir):
    print "Output directory doesn't exist. Creating it..."
    os.makedirs(opts.out_dir)
  if not os.path.exists(opts.cache):
    print "Cache directory doesn't exist."
    return False
  return True


def _ParseFilename(filename, canonical=False):
  """Returns a tuple (key, time, board, lsb_version).
     If canonical is True, instead returns (database_key, board, canonical_vers)
     canonical_vers includes the revision string.
  """
  key, time, board, vers = filename.split('~')
  if canonical:
    vers = misc.GetChromeOSVersionFromLSBVersion(vers)
  return (key, time, board, vers)


def _FormReleaseDir(board, version):
  return '%s-release~%s' % (board, version)


def _DownloadSymbols(filename, cache):
  """ Incrementally downloads appropriate symbols.
      We store the downloads in cache, with each set of symbols in a TLD
      named like cache/$board-release~$canonical_vers/usr/lib/debug
  """
  _, _, board, vers = _ParseFilename(filename, canonical=True)
  tmp_suffix = '.tmp'

  tarball_subdir = _FormReleaseDir(board, vers)
  tarball_dir = os.path.join(cache, tarball_subdir)
  tarball_path = os.path.join(tarball_dir, 'debug.tgz')

  symbol_subdir = os.path.join('usr', 'lib')
  symbol_dir = os.path.join(tarball_dir, symbol_subdir)

  if os.path.isdir(symbol_dir):
    print 'Symbol directory %s exists, skipping download.' % symbol_dir
    return
  else:
    # First download using gsutil.
    if not os.path.isfile(tarball_path):
      download_cmd = GSUTIL_CMD % (board, vers, tarball_path + tmp_suffix)
      print 'Downloading symbols for %s' % filename
      print download_cmd
      ret = call(download_cmd.split())
      if ret != 0:
        print 'gsutil returned non-zero error code: %s.' % ret
        # Clean up the empty directory structures.
        os.remove(tarball_path + tmp_suffix)
        raise IOError

      shutil.move(tarball_path + tmp_suffix, tarball_path)

    # Next, untar the tarball.
    os.makedirs(symbol_dir + tmp_suffix)
    extract_cmd = TAR_CMD % (tarball_path, symbol_dir + tmp_suffix)
    print 'Extracting symbols for %s' % filename
    print extract_cmd
    ret = call(extract_cmd.split())
    if ret != 0:
      print 'tar returned non-zero code: %s.' % ret
      raise IOError
    shutil.move(symbol_dir + tmp_suffix, symbol_dir)
    os.remove(tarball_path)


def _PerfReport(filename, in_dir, out_dir, cache):
  """ Call perf report on the file, storing output to the output dir.
      The output is currently stored as $out_dir/$filename
  """
  _, _, board, vers = _ParseFilename(filename, canonical=True)
  symbol_cache_tld = _FormReleaseDir(board, vers)
  input_file = os.path.join(in_dir, filename)
  symfs = os.path.join(cache, symbol_cache_tld)
  report_cmd = PERF_CMD % (input_file, symfs)
  print 'Reporting.'
  print report_cmd
  report_proc = Popen(report_cmd.split(), stdout=PIPE)
  outfile = open(os.path.join(out_dir, filename), 'w')
  outfile.write(report_proc.stdout.read())
  outfile.close()


if __name__ == '__main__':
  exit(main())
