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

import datetime
import optparse
import os
import smtplib
import sys
import time
from email.mime.text import MIMEText

from autotest_gatherer import AutotestGatherer as AutotestGatherer
from autotest_run import AutotestRun as AutotestRun
from machine_manager_singleton import MachineManagerSingleton as MachineManagerSingleton
from utils import logger
from utils.file_utils import FileUtils


def CanonicalizeChromeOSRoot(chromeos_root):
  chromeos_root = os.path.expanduser(chromeos_root)
  if os.path.isfile(os.path.join(chromeos_root,
                                 "src/scripts/enter_chroot.sh")):
    return chromeos_root
  else:
    return None


class Autotest(object):
  def __init__(self, autotest_string):
    self.name = None
    self.iterations = None
    self.args = None
    fields = autotest_string.split(",", 1)
    self.name = fields[0]
    if len(fields) > 1:
      autotest_string = fields[1]
      fields = autotest_string.split(",", 1)
    else: return
    self.iterations = int(fields[0])
    if len(fields) > 1:
      self.args = fields[1]
    else: return

  def __str__(self):
    return "\n".join([self.name, self.iterations, self.args])


def CreateAutotestListFromString(autotest_strings, default_iterations=None):
  autotest_list = []
  for autotest_string in autotest_strings.split(":"):
    autotest = Autotest(autotest_string)
    if default_iterations and not autotest.iterations:
      autotest.iterations = default_iterations

    autotest_list.append(autotest)
  return autotest_list


def CreateAutotestRuns(images, autotests, remote, board, exact_remote,
                       rerun, rerun_if_failed, main_chromeos_root=None):
  autotest_runs = []
  for image in images:
    logger.GetLogger().LogOutput("Computing md5sum of: %s" % image)
    image_checksum = FileUtils().Md5File(image)
    logger.GetLogger().LogOutput("md5sum %s: %s" % (image, image_checksum))
###    image_checksum = "abcdefghi"

    chromeos_root = main_chromeos_root
    if not main_chromeos_root:
      image_chromeos_root = os.path.join(os.path.dirname(image),
                                         "../../../../..")
      chromeos_root = CanonicalizeChromeOSRoot(image_chromeos_root)
      assert chromeos_root, "chromeos_root: %s invalid" % image_chromeos_root
    else:
      chromeos_root = CanonicalizeChromeOSRoot(main_chromeos_root)
      assert chromeos_root, "chromeos_root: %s invalid" % main_chromeos_root

    # We just need a single ChromeOS root in the MachineManagerSingleton. It is
    # needed because we can save re-image time by checking the image checksum at
    # the beginning and assigning autotests to machines appropriately.
    if not MachineManagerSingleton().chromeos_root:
      MachineManagerSingleton().chromeos_root = chromeos_root

    for autotest in autotests:
      for iteration in range(autotest.iterations):
        autotest_run = AutotestRun(autotest,
                                   chromeos_root=chromeos_root,
                                   chromeos_image=image,
                                   board=board,
                                   remote=remote,
                                   iteration=iteration,
                                   image_checksum=image_checksum,
                                   exact_remote=exact_remote,
                                   rerun=rerun,
                                   rerun_if_failed=rerun_if_failed)
        autotest_runs.append(autotest_run)
  return autotest_runs


def GetNamesAndIterations(autotest_runs):
  strings = []
  for autotest_run in autotest_runs:
    strings.append("%s:%s" % (autotest_run.autotest.name,
                              autotest_run.iteration))
  return " %s (%s)" % (len(strings), " ".join(strings))


def GetStatusString(autotest_runs):
  status_bins = {}
  for autotest_run in autotest_runs:
    if autotest_run.status not in status_bins:
      status_bins[autotest_run.status] = []
    status_bins[autotest_run.status].append(autotest_run)

  status_strings = []
  for key, val in status_bins.items():
    status_strings.append("%s: %s" % (key, GetNamesAndIterations(val)))
  return "Thread Status:\n%s" % "\n".join(status_strings)


def GetProgressBar(num_done, num_total):
  ret = "Done: %s%%" % int(100.0 * num_done / num_total)
  bar_length = 50
  done_char = ">"
  undone_char = " "
  num_done_chars = bar_length * num_done / num_total
  num_undone_chars = bar_length - num_done_chars
  ret += " [%s%s]" % (num_done_chars * done_char, num_undone_chars *
                      undone_char)
  return ret


def GetProgressString(start_time, num_remain, num_total):
  current_time = time.time()
  elapsed_time = current_time - start_time
  try:
    eta_seconds = float(num_remain) * elapsed_time / (num_total - num_remain)
    eta_seconds = int(eta_seconds)
    eta = datetime.timedelta(seconds=eta_seconds)
  except ZeroDivisionError:
    eta = "Unknown"
  strings = []
  strings.append("Current time: %s Elapsed: %s ETA: %s" %
          (datetime.datetime.now(),
           datetime.timedelta(seconds=int(elapsed_time)),
           eta))
  strings.append(GetProgressBar(num_total - num_remain, num_total))
  return "\n".join(strings)


def RunAutotestRunsInParallel(autotest_runs):
  start_time = time.time()
  active_threads = []
  for autotest_run in autotest_runs:
    # Set threads to daemon so program exits when ctrl-c is pressed.
    autotest_run.daemon = True
    autotest_run.start()
    active_threads.append(autotest_run)

  print_interval = 30
  last_printed_time = time.time()
  while active_threads:
    try:
      active_threads = [t for t in active_threads if t is not None
                        and t.isAlive()]
      for t in active_threads:
        t.join(1)
      if time.time() - last_printed_time > print_interval:
        border = "=============================="
        logger.GetLogger().LogOutput(border)
        logger.GetLogger().LogOutput(GetProgressString(
            start_time,
            len([t for t in autotest_runs if t.status not in ["SUCCEEDED",
                                                              "FAILED"]]),
            len(autotest_runs)))
        logger.GetLogger().LogOutput(GetStatusString(autotest_runs))
        logger.GetLogger().LogOutput("%s\n" %
                                     MachineManagerSingleton().AsString())
        logger.GetLogger().LogOutput(border)
        last_printed_time = time.time()
    except KeyboardInterrupt:
      print "C-c received... cleaning up threads."
      for t in active_threads:
        t.terminate = True
      return 1
  return 0


def RunAutotestRunsSerially(autotest_runs):
  for autotest_run in autotest_runs:
    retval = autotest_run.Run()
    if retval: return retval


def ProduceTables(autotest_runs, full_table, fit_string):
  l = logger.GetLogger()
  ags_dict = {}
  for autotest_run in autotest_runs:
    name = autotest_run.full_name
    if name not in ags_dict:
      ags_dict[name] = AutotestGatherer()
    ags_dict[name].runs.append(autotest_run)
    output = ""
  for b, ag in ags_dict.items():
    output += "Benchmark: %s\n" % b
    output += ag.GetFormattedMainTable(percents_only=not full_table,
                                       fit_string=fit_string)
    output += "\n"

  summary = ""
  for b, ag in ags_dict.items():
    summary += "Benchmark Summary Table: %s\n" % b
    summary += ag.GetFormattedSummaryTable(percents_only=not full_table,
                                           fit_string=fit_string)
    summary += "\n"

  output += summary
  output += ("Number of re-images performed: %s" %
             MachineManagerSingleton().num_reimages)
  l.LogOutput(output)

  if autotest_runs:
    board = autotest_runs[0].board
  else:
    board = ""

  subject = "%s: %s" % (board, ", ".join(ags_dict.keys()))

  if any(autotest_run.run_completed for autotest_run in autotest_runs):
    SendEmailToUser(subject, summary)


def SendEmailToUser(subject, text_to_send):
  # Email summary to the current user.
  msg = MIMEText(text_to_send)

  # me == the sender's email address
  # you == the recipient's email address
  me = os.path.basename(__file__)
  you = os.getlogin()
  msg["Subject"] = "[%s] %s" % (os.path.basename(__file__), subject)
  msg["From"] = me
  msg["To"] = you

  # Send the message via our own SMTP server, but don't include the
  # envelope header.
  s = smtplib.SMTP("localhost")
  s.sendmail(me, [you], msg.as_string())
  s.quit()


def Main(argv):
  """The main function."""
  # Common initializations
###  command_executer.InitCommandExecuter(True)
  l = logger.GetLogger()

  parser = optparse.OptionParser()
  parser.add_option("-t", "--tests", dest="tests",
                    help=("Tests to compare."
                          "Optionally specify per-test iterations by:"
                          "<test>,<iter>:<args>"))
  parser.add_option("-c", "--chromeos_root", dest="chromeos_root",
                    help="A *single* chromeos_root where scripts can be found.")
  parser.add_option("-n", "--iterations", dest="iterations",
                    help="Iterations to run per benchmark.",
                    default=1)
  parser.add_option("-r", "--remote", dest="remote",
                    help="The remote chromeos machine.")
  parser.add_option("-b", "--board", dest="board",
                    help="The remote board.")
  parser.add_option("--full_table", dest="full_table",
                    help="Print full tables.",
                    action="store_true",
                    default=True)
  parser.add_option("--exact_remote",
                    dest="exact_remote",
                    help="Run tests on the exact remote.",
                    action="store_true",
                    default=False)
  parser.add_option("--fit_string", dest="fit_string",
                    help="Fit strings to fixed sizes.",
                    action="store_true",
                    default=False)
  parser.add_option("--rerun",
                    dest="rerun",
                    help="Re-run regardless of cache hit.",
                    action="store_true",
                    default=False)
  parser.add_option("--rerun_if_failed",
                    dest="rerun_if_failed",
                    help="Re-run if previous run was a failure.",
                    action="store_true",
                    default=False)
  parser.add_option("--no_lock",
                    dest="no_lock",
                    help="Do not lock the machine before running the tests.",
                    action="store_true",
                    default=False)
  l.LogOutput(" ".join(argv))
  [options, args] = parser.parse_args(argv)

  if options.remote is None:
    l.LogError("No remote machine specified.")
    parser.print_help()
    return 1

  if not options.board:
    l.LogError("No board specified.")
    parser.print_help()
    return 1

  remote = options.remote
  tests = options.tests
  board = options.board
  exact_remote = options.exact_remote
  iterations = int(options.iterations)

  autotests = CreateAutotestListFromString(tests, iterations)

  main_chromeos_root = options.chromeos_root
  images = args[1:]
  fit_string = options.fit_string
  full_table = options.full_table
  rerun = options.rerun
  rerun_if_failed = options.rerun_if_failed

  MachineManagerSingleton().no_lock = options.no_lock

  # Now try creating all the Autotests
  autotest_runs = CreateAutotestRuns(images, autotests, remote, board,
                                     exact_remote, rerun, rerun_if_failed,
                                     main_chromeos_root)

  try:
    # At this point we have all the autotest runs.
    for machine in remote.split(","):
      MachineManagerSingleton().AddMachine(machine)

    retval = RunAutotestRunsInParallel(autotest_runs)
    if retval: return retval

    # Now print tables
    ProduceTables(autotest_runs, full_table, fit_string)
  finally:
    # not sure why this isn't called at the end normally...
    MachineManagerSingleton().__del__()

  return 0

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