#!/usr/bin/python2
#
# 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 ./dejagnu/run_dejagnu.py
"""

from __future__ import print_function

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

import argparse
import sys
import setup_chromeos
import build_tc

from dejagnu import run_dejagnu
from cros_utils import command_executer
from cros_utils import email_sender


class DejagnuAdapter(object):
  """Dejagnu Adapter class"""

  # 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(input_str):
  if not input_str:
    return 0
  start_counting = False
  n_failures = 0
  for l in input_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']
  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 = argparse.ArgumentParser(
      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_argument('-b',
                      '--board',
                      dest='board',
                      help=('Required. Specify board type. For example '
                            '\'lumpy\' and \'daisy\''))
  parser.add_argument('-r',
                      '--remote',
                      dest='remote',
                      help=('Required. Specify remote board address'))
  parser.add_argument('-g',
                      '--gcc_dir',
                      dest='gcc_dir',
                      default='gcc.live',
                      help=('Optional. Specify gcc checkout directory.'))
  parser.add_argument('-c',
                      '--chromeos_root',
                      dest='chromeos_root',
                      default='chromeos.live',
                      help=('Optional. Specify chromeos checkout directory.'))
  parser.add_argument('--cleanup',
                      dest='cleanup',
                      default=None,
                      help=('Optional. Do cleanup after the test.'))
  parser.add_argument('--runtestflags',
                      dest='runtestflags',
                      default=None,
                      help=('Optional. Options to RUNTESTFLAGS env var '
                            'while invoking make check. '
                            '(Mainly used for testing purpose.)'))

  options = parser.parse_args(argv[1:])

  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])
