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

"""Script adapter used by automation client for testing dejagnu.
   This is not intended to be run on command line.
   To kick off a single dejagnu run, use chromeos/v14/dejagnu/run_dejagnu.py
"""

__author__ = 'shenhan@google.com (Han Shen)'

import optparse
import os
from os import path
import sys
import setup_chromeos
import build_tc

from dejagnu import run_dejagnu
from utils import command_executer
from utils import email_sender

class DejagnuAdapter(object):

  # TODO(shenhan): move these to constants.py.
  _CHROMIUM_GCC_GIT = ("https://chromium.googlesource.com/"
                       "chromiumos/third_party/gcc.git")
  _CHROMIUM_GCC_BRANCH = "gcc.gnu.org/branches/google/gcc-4_7-mobile"

  _cmd_exec = command_executer.GetCommandExecuter()

  def __init__(self, board, remote, gcc_dir,
               chromeos_root, runtestflags, cleanup):
    self._board = board
    self._remote = remote
    self._gcc_dir = gcc_dir
    self._chromeos_root = chromeos_root
    self._runtestflags = runtestflags
    self._cleanup = cleanup

  def SetupChromeOS(self):
    cmd = [setup_chromeos.__file__,
           "--dir=" + self._chromeos_root, "--minilayout", "--jobs=8"]
    ret = setup_chromeos.Main(cmd)
    if ret:
      raise Exception("Failed to checkout chromeos")
    ## Do cros_sdk and setup_board, otherwise build_tc in next step will fail.
    cmd = "cd {0} && cros_sdk --download".format(self._chromeos_root)
    ret = self._cmd_exec.RunCommand(cmd, terminated_timeout=9000)
    if ret:
      raise Exception("Failed to create chroot.")

  def SetupBoard(self):
    cmd = "./setup_board --board=" + self._board
    ret = self._cmd_exec.ChrootRunCommand(self._chromeos_root,
                                          cmd, terminated_timeout=4000)
    if ret:
      raise Exception("Failed to setup board.")

  def CheckoutGCC(self):
    cmd = "git clone {0} {1} && cd {1} && git checkout {2}".format(
      self._CHROMIUM_GCC_GIT, self._gcc_dir, self._CHROMIUM_GCC_BRANCH)

    ret = self._cmd_exec.RunCommand(cmd, terminated_timeout=300)
    if ret:
      raise Exception("Failed to checkout gcc.")
    ## Handle build_tc bug.
    cmd = ("touch {0}/gcc/config/arm/arm-tune.md " + \
        "{0}/gcc/config/arm/arm-tables.opt").format(self._gcc_dir)
    ret = self._cmd_exec.RunCommand(cmd)

  def BuildGCC(self):
    build_gcc_args = [build_tc.__file__,
                      "--board=" + self._board,
                      "--chromeos_root=" + self._chromeos_root,
                      "--gcc_dir=" + self._gcc_dir]
    ret = build_tc.Main(build_gcc_args)
    if ret:
      raise Exception("Building gcc failed.")

  def CheckGCC(self):
    args = [run_dejagnu.__file__,
            "--board=" + self._board,
            "--chromeos_root=" + self._chromeos_root,
            "--mount=" + self._gcc_dir,
            "--remote=" + self._remote]
    if self._cleanup:
      args.append("--cleanup=" + self._cleanup)
    if self._runtestflags:
      args.append("--flags=" + self._runtestflags)
    return run_dejagnu.Main(args)


# Parse the output log to determine how many failures we have.
# Return -1 if parse output log failed.
def GetNumNewFailures(str):
  if not str:
    return 0
  start_counting = False
  n_failures = 0
  for l in str.splitlines():
    print l
    if not start_counting and 'Build results not in the manifest' in l:
      start_counting = True
    elif start_counting and l and (
      l.find('UNRESOLVED:') == 0 or l.find('FAIL:') == 0 or \
        l.find('XFAIL:') == 0 or l.find('XPASS:') == 0):
      n_failures = n_failures + 1
  if not start_counting:
    return -1
  return n_failures

# Do not throw any exception in this function!
def EmailResult(result):
  email_to = ['c-compiler-chrome@google.com']
  email_from = ['dejagnu-job@google.com']
  if len(result) == 4:
    subject = 'Job failed: dejagnu test didn\'t finish'
    email_text = 'Job failed prematurely, check exception below.\n' + \
        result[3]
  elif result[0]:
    subject = 'Job finished: dejagnu test failed'
    num_new_failures = GetNumNewFailures(result[1])
    if num_new_failures >= 0:
      summary = '{0} new fail(s), check log below.'.format(num_new_failures)
    else:
      summary = 'At least 1 new fail found, check log below.'
    email_text = summary + \
        ('\nStdout ====\n'
         '{0}\n'
         '\nStderr ===\n'
         '{1}\n').format(result[1], result[2])
  else:
    subject = 'Job finished: dejagnu test passed'
    email_text = ('Cool! No new fail found.\n'
                  '\nStdout ====\n'
                  '{0}\n'
                  '\nStderr ====\n'
                  '{1}\n').format(result[1], result[2])

  try:
    email_sender.EmailSender().SendEmail(email_to, subject, email_text)
    print 'Email sent.'
  except Exception as e:
    # Do not propagate this email sending exception, you want to email an
    # email exception? Just log it on console.
    print ('Sending email failed - {0}'
           'Subject: {1}'
           'Text: {2}').format(
      str(e), subject, email_text)


def ProcessArguments(argv):
  """Processing script arguments."""
  parser = optparse.OptionParser(description=(
      'This script is used by nightly client to test gcc. '
      'DO NOT run it unless you know what you are doing.'),
      usage='test_gcc_dejagnu.py options')
  parser.add_option('-b', '--board', dest='board',
                    help=('Required. Specify board type. For example '
                          '\'lumpy\' and \'daisy\''))
  parser.add_option('-r', '--remote', dest='remote',
                    help=('Required. Specify remote board address'))
  parser.add_option('-g', '--gcc_dir', dest='gcc_dir', default='gcc.live',
                    help=('Optional. Specify gcc checkout directory.'))
  parser.add_option('-c', '--chromeos_root', dest='chromeos_root',
                    default='chromeos.live',
                    help=('Optional. Specify chromeos checkout directory.'))
  parser.add_option('--cleanup', dest='cleanup', default=None,
                    help=('Optional. Do cleanup after the test.'))
  parser.add_option('--runtestflags', dest='runtestflags', default=None,
                    help=('Optional. Options to RUNTESTFLAGS env var '
                          'while invoking make check. '
                          '(Mainly used for testing purpose.)'))

  options, args = parser.parse_args(argv)

  if not options.board or not options.remote:
    raise Exception("--board and --remote are mandatory options.")

  return options


def Main(argv):
  opt = ProcessArguments(argv)
  adapter = DejagnuAdapter(
    opt.board, opt.remote, opt.gcc_dir, opt.chromeos_root,
    opt.runtestflags, opt.cleanup)
  try:
    adapter.SetupChromeOS()
    adapter.SetupBoard()
    adapter.CheckoutGCC()
    adapter.BuildGCC()
    ret = adapter.CheckGCC()
  except Exception as e:
    print e
    ret = (1, '', '', str(e))
  finally:
    EmailResult(ret)
    return ret


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