#!/usr/bin/python2
#
# 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 cros_utils import command_executer
from cros_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)
