#!/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])
