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

"""Script to divide and merge profiles."""

import copy
import optparse
import os
import pickle
import re
import sys
import tempfile

import build_chrome_browser
import lock_machine
import run_tests
from utils import command_executer
from utils import logger


class ProfileMerger:
  def __init__(self, inputs, output, chunk_size, merge_program, multipliers):
    self._inputs = inputs
    self._output = output
    self._chunk_size = chunk_size
    self._merge_program = merge_program
    self._multipliers = multipliers
    self._ce = command_executer.GetCommandExecuter()
    self._l = logger.GetLogger()

  def _GetFilesSetForInputDir(self, input_dir):
    output_file = tempfile.mktemp()
    command = "find %s -name '*.gcda' -o -name '*.imports' > %s" % (input_dir, output_file)
    self._ce.RunCommand(command)
    files = open(output_file, "r").read()
    files_set = set([])
    for f in files.splitlines():
      stripped_file = f.replace(input_dir, "", 1)
      stripped_file = stripped_file.lstrip("/")
      files_set.add(stripped_file)
    return files_set

  def _PopulateFilesSet(self):
    self._files_set = set([])
    for i in self._inputs:
      current_files_set = self._GetFilesSetForInputDir(i)
      self._files_set.update(current_files_set)

  def _GetSubset(self):
    ret = []
    for i in range(self._chunk_size):
      if not self._files_set:
        break
      ret.append(self._files_set.pop())
    return ret

  def _CopyFilesTree(self, input_dir, files, output_dir):
    for f in files:
      src_file = os.path.join(input_dir, f)
      dst_file = os.path.join(output_dir, f)
      if not os.path.isdir(os.path.dirname(dst_file)):
        command = "mkdir -p %s" % os.path.dirname(dst_file)
        self._ce.RunCommand(command)
      command = "cp %s %s" % (src_file, dst_file)
      self._ce.RunCommand(command)

  def _DoChunkMerge(self, current_files):
    temp_dirs = []
    for i in self._inputs:
      temp_dir = tempfile.mkdtemp()
      temp_dirs.append(temp_dir)
      self._CopyFilesTree(i, current_files, temp_dir)
    # Now do the merge.
    command = ("%s --inputs=%s --output=%s" %
               (self._merge_program,
                ",".join(temp_dirs),
                self._output))
    if self._multipliers:
      command = ("%s --multipliers=%s" %
                 (command, self._multipliers))
    ret = self._ce.RunCommand(command)
    assert ret == 0, "%s command failed!" % command
    for temp_dir in temp_dirs:
      command = "rm -rf %s" % temp_dir
      self._ce.RunCommand(command)

  def DoMerge(self):
    self._PopulateFilesSet()
    while True:
      current_files = self._GetSubset()
      if not current_files:
        break
      self._DoChunkMerge(current_files)


def Main(argv):
  """The main function."""
  # Common initializations
###  command_executer.InitCommandExecuter(True)
  command_executer.InitCommandExecuter()
  l = logger.GetLogger()
  ce = command_executer.GetCommandExecuter()
  parser = optparse.OptionParser()
  parser.add_option("--inputs",
                    dest="inputs",
                    help="Comma-separated input profile directories to merge.")
  parser.add_option("--output",
                    dest="output",
                    help="Output profile directory.")
  parser.add_option("--chunk_size",
                    dest="chunk_size",
                    default="50",
                    help="Chunk size to divide up the profiles into.")
  parser.add_option("--merge_program",
                    dest="merge_program",
                    default="/home/xur/bin/profile_merge_v15.par",
                    help="Merge program to use to do the actual merge.")
  parser.add_option("--multipliers",
                    dest="multipliers",
                    help="multipliers to use when merging. (optional)")

  options, _ = parser.parse_args(argv)

  if not all([options.inputs,
              options.output,]):
    l.LogError("Must supply --inputs and --output")
    return 1

  try:
    pm = ProfileMerger(options.inputs.split(","), options.output,
                       int(options.chunk_size), options.merge_program,
                       options.multipliers)
    pm.DoMerge()
    retval = 0
  except:
    retval = 1
  finally:
    print "My work is done..."
  return retval


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