#!/usr/bin/python
#
# Copyright 2011 Google Inc. All Rights Reserved.

"""Script to build chrome with FDO and compare performance against no FDO."""

import getpass
import optparse
import os
import sys

import image_chromeos
import setup_chromeos
from utils import command_executer
from utils import misc
from utils import logger


class Patcher(object):
  def __init__(self, dir_to_patch, patch_file):
    self._dir_to_patch = dir_to_patch
    self._patch_file = patch_file
    self._base_patch_command = "patch -p0 %%s < %s" % patch_file
    self._ce = command_executer.GetCommandExecuter()

  def _RunPatchCommand(self, args):
    patch_command = self._base_patch_command % args
    command = ("cd %s && %s" % (self._dir_to_patch,
                                patch_command))
    return self._ce.RunCommand(command)

  def _ApplyPatch(self, args):
    full_args = "%s --dry-run" % args
    ret = self._RunPatchCommand(full_args)
    if ret:
      raise Exception("Patch dry run failed!")
    ret = self._RunPatchCommand(args)
    if ret:
      raise Exception("Patch application failed!")

  def __enter__(self):
    self._ApplyPatch("")

  def __exit__(self, type, value, traceback):
    self._ApplyPatch("-R")


class FDOComparator(object):
  def __init__(self, board, remotes, ebuild_version, plus_pgo, minus_pgo,
               update_pgo, chromeos_root):
    self._board = board
    self._remotes = remotes
    self._ebuild_version = ebuild_version
    self._remote = remotes.split(",")[0]
    self._chromeos_root = chromeos_root
    self._profile_dir = "profile_dir"
    self._profile_path = os.path.join(self._chromeos_root,
                                      "src",
                                      "scripts",
                                      os.path.basename(self._profile_dir))
    self._plus_pgo = plus_pgo
    self._minus_pgo = minus_pgo
    self._update_pgo = update_pgo

    self._ce = command_executer.GetCommandExecuter()
    self._l = logger.GetLogger()

  def _CheckoutChromeOS(self):
    if not os.path.exists(self._chromeos_root):
      setup_chromeos_args = [setup_chromeos.__file__,
                             "--dir=%s" % self._chromeos_root,
                             "--minilayout"]
      setup_chromeos.Main(setup_chromeos_args)

  def _BuildChromeOSUsingBinaries(self):
    image_dir = misc.GetImageDir(self._chromeos_root, self._board)
    command = "equery-%s l chromeos" % self._board
    ret = self._ce.ChrootRunCommand(self._chromeos_root, command)
    if ret:
      command = misc.GetSetupBoardCommand(self._board,
                                           usepkg=True)
      ret = self._ce.ChrootRunCommand(self._chromeos_root,
                                      command)
      if ret:
        raise Exception("Couldn't run setup_board!")
      command = misc.GetBuildPackagesCommand(self._board,
                                              True)
      ret = self._ce.ChrootRunCommand(self._chromeos_root,
                                    command)
      if ret:
        raise Exception("Couldn't run build_packages!")

  def _ReportMismatches(self, build_log):
    mismatch_signature = "-Wcoverage-mismatch"
    mismatches = build_log.count(mismatch_signature)
    self._l.LogOutput("Total mismatches: %s" % mismatches)
    stale_files = set([])
    for line in build_log.splitlines():
      if mismatch_signature in line:
        filename = line.split(":")[0]
        stale_files.add(filename)
    self._l.LogOutput("Total stale files: %s" % len(stale_files))

  def _BuildChromeAndImage(self, ebuild_version="", env_dict={}, cflags="",
                           cxxflags="", ldflags="", label="",
                           build_image_args=""):
    env_string = misc.GetEnvStringFromDict(env_dict)
    if not label:
      label = " ".join([env_string,
                        cflags,
                        cxxflags,
                        ldflags,
                        ebuild_version])
      label = label.strip()
      label = misc.GetFilenameFromString(label)
    if not misc.DoesLabelExist(self._chromeos_root, self._board, label):
      build_chrome_browser_args = ["--clean",
                                   "--chromeos_root=%s" % self._chromeos_root,
                                   "--board=%s" % self._board,
                                   "--env=%r" % env_string,
                                   "--cflags=%r" % cflags,
                                   "--cxxflags=%r" % cxxflags,
                                   "--ldflags=%r" % ldflags,
                                   "--ebuild_version=%s" % ebuild_version,
                                   "--build_image_args=%s" % build_image_args]

      build_chrome_browser = os.path.join(os.path.dirname(__file__),
                                          "..",
                                          "build_chrome_browser.py")
      command = "python %s %s" % (build_chrome_browser,
                                  " ".join(build_chrome_browser_args))
      ret, out, err = self._ce.RunCommand(command,
                                          return_output=True)
      if "-fprofile-use" in cxxflags:
        self._ReportMismatches(out)

      if ret:
        raise Exception("Couldn't build chrome browser!")
      misc.LabelLatestImage(self._chromeos_root, self._board, label)
    return label

  def _TestLabels(self, labels):
    experiment_file = "pgo_experiment.txt"
    experiment_header = """
    board: %s
    remote: %s
    """ % (self._board, self._remotes)
    experiment_tests = """
    benchmark: desktopui_PyAutoPerfTests {
      iterations: 1
    }
    """
    with open(experiment_file, "w") as f:
      print >>f, experiment_header
      print >>f, experiment_tests
      for label in labels:
        # TODO(asharif): Fix crosperf so it accepts labels with symbols
        crosperf_label = label
        crosperf_label = crosperf_label.replace("-", "minus")
        crosperf_label = crosperf_label.replace("+", "plus")
        experiment_image = """
        %s {
          chromeos_image: %s
        }
        """ % (crosperf_label,
               os.path.join(misc.GetImageDir(self._chromeos_root, self._board),
                            label,
                            "chromiumos_test_image.bin"))
        print >>f, experiment_image
    crosperf = os.path.join(os.path.dirname(__file__),
                            "..",
                            "crosperf",
                            "crosperf")
    command = "%s %s" % (crosperf, experiment_file)
    ret = self._ce.RunCommand(command)
    if ret:
      raise Exception("Couldn't run crosperf!")

  def _ImageRemote(self, label):
    image_path = os.path.join(misc.GetImageDir(self._chromeos_root,
                                                self._board),
                              label,
                              "chromiumos_test_image.bin")
    image_chromeos_args = [image_chromeos.__file__,
                           "--chromeos_root=%s" % self._chromeos_root,
                           "--image=%s" % image_path,
                           "--remote=%s" % self._remote,
                           "--board=%s" % self._board]
    image_chromeos.Main(image_chromeos_args)

  def _ProfileRemote(self):
    profile_cycler = os.path.join(os.path.dirname(__file__),
                                  "profile_cycler.py")
    profile_cycler_args = ["--chromeos_root=%s" % self._chromeos_root,
                           "--cycler=all",
                           "--board=%s" % self._board,
                           "--profile_dir=%s" % self._profile_path,
                           "--remote=%s" % self._remote]
    command = "python %s %s" % (profile_cycler, " ".join(profile_cycler_args))
    ret = self._ce.RunCommand(command)
    if ret:
      raise Exception("Couldn't profile cycler!")

  def _BuildGenerateImage(self):
    # TODO(asharif): add cflags as well.
    labels_list = ["fprofile-generate", self._ebuild_version]
    label = "_".join(labels_list)
    generate_label = self._BuildChromeAndImage(
        env_dict={"USE": "chrome_internal -pgo pgo_generate"},
        label=label,
        ebuild_version=self._ebuild_version,
        build_image_args="--rootfs_boost_size=400")
    return generate_label

  def _BuildUseImage(self):
    ctarget = misc.GetCtargetFromBoard(self._board, self._chromeos_root)
    chroot_profile_dir = os.path.join("/home/%s/trunk" % getpass.getuser(),
                                      "src",
                                      "scripts",
                                      self._profile_dir,
                                      ctarget)
    cflags = ("-fprofile-use "
              "-fprofile-correction "
              "-Wno-error "
              "-fdump-tree-optimized-blocks-lineno "
              "-fdump-ipa-profile-blocks-lineno "
              "-fno-vpt "
              "-fprofile-dir=%s" %
              chroot_profile_dir)
    labels_list = ["updated_pgo", self._ebuild_version]
    label = "_".join(labels_list)
    pgo_use_label = self._BuildChromeAndImage(
        env_dict={"USE": "chrome_internal -pgo"},
        cflags=cflags,
        cxxflags=cflags,
        ldflags=cflags,
        label=label,
        ebuild_version=self._ebuild_version)
    return pgo_use_label

  def DoAll(self):
    self._CheckoutChromeOS()
    self._BuildChromeOSUsingBinaries()
    labels = []

    if self._minus_pgo:
      minus_pgo = self._BuildChromeAndImage(env_dict={"USE": "chrome_internal -pgo"},
                                            ebuild_version=self._ebuild_version)
      labels.append(minus_pgo)
    if self._plus_pgo:
      plus_pgo = self._BuildChromeAndImage(env_dict={"USE": "chrome_internal pgo"},
                                           ebuild_version=self._ebuild_version)
      labels.append(plus_pgo)

    if self._update_pgo:
      if not os.path.exists(self._profile_path):
        # Build Chrome with -fprofile-generate
        generate_label = self._BuildGenerateImage()
        # Image to the remote box.
        self._ImageRemote(generate_label)
        # Profile it using all page cyclers.
        self._ProfileRemote()

      # Use the profile directory to rebuild it.
      updated_pgo_label = self._BuildUseImage()
      labels.append(updated_pgo_label)

    # Run crosperf on all images now.
    self._TestLabels(labels)
    return 0


def Main(argv):
  """The main function."""
  # Common initializations
###  command_executer.InitCommandExecuter(True)
  command_executer.InitCommandExecuter()
  parser = optparse.OptionParser()
  parser.add_option("--remote",
                    dest="remote",
                    help="Remote machines to run tests on.")
  parser.add_option("--board",
                    dest="board",
                    default="x86-zgb",
                    help="The target board.")
  parser.add_option("--ebuild_version",
                    dest="ebuild_version",
                    default="",
                    help="The Chrome ebuild version to use.")
  parser.add_option("--plus_pgo",
                    dest="plus_pgo",
                    action="store_true",
                    default=False,
                    help="Build USE=+pgo.")
  parser.add_option("--minus_pgo",
                    dest="minus_pgo",
                    action="store_true",
                    default=False,
                    help="Build USE=-pgo.")
  parser.add_option("--update_pgo",
                    dest="update_pgo",
                    action="store_true",
                    default=False,
                    help="Update pgo and build Chrome with the update.")
  parser.add_option("--chromeos_root",
                    dest="chromeos_root",
                    default=False,
                    help="The chromeos root directory")
  options, _ = parser.parse_args(argv)
  if not options.board:
    print "Please give a board."
    return 1
  if not options.remote:
    print "Please give at least one remote machine."
    return 1
  if not options.chromeos_root:
    print "Please provide the chromeos root directory."
    return 1
  if not any((options.minus_pgo, options.plus_pgo, options.update_pgo)):
    print "Please provide at least one build option."
    return 1
  fc = FDOComparator(options.board,
                     options.remote,
                     options.ebuild_version,
                     options.plus_pgo,
                     options.minus_pgo,
                     options.update_pgo,
                     os.path.expanduser(options.chromeos_root))
  return fc.DoAll()


if __name__ == "__main__":
  retval = Main(sys.argv)
  sys.exit(retval)
