#!/usr/bin/python
# 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())
