#!/usr/bin/python
# Copyright (c) 2011 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE.chromium.TXT file.

import copy
import re
import time


from buildbot import util
from buildbot.process import buildstep
from buildbot.process.properties import WithProperties
from buildbot.status import builder
from buildbot.steps import shell
from buildbot.steps import source


class BuilderStatus(object):
  # Order in asceding severity.
  BUILD_STATUS_ORDERING = [
      builder.SUCCESS,
      builder.WARNINGS,
      builder.FAILURE,
      builder.EXCEPTION,
  ]

  @classmethod
  def combine(cls, a, b):
    """Combine two status, favoring the more severe."""
    if a not in cls.BUILD_STATUS_ORDERING:
      return b
    if b not in cls.BUILD_STATUS_ORDERING:
      return a
    a_rank = cls.BUILD_STATUS_ORDERING.index(a)
    b_rank = cls.BUILD_STATUS_ORDERING.index(b)
    pick = max(a_rank, b_rank)
    return cls.BUILD_STATUS_ORDERING[pick]


class ProcessLogShellStep(shell.ShellCommand):
  """ Step that can process log files.

    Delegates actual processing to log_processor, which is a subclass of
    process_log.PerformanceLogParser.

    Sample usage:
    # construct class that will have no-arg constructor.
    log_processor_class = chromium_utils.PartiallyInitialize(
        process_log.GraphingPageCyclerLogProcessor,
        report_link='http://host:8010/report.html,
        output_dir='~/www')
    # We are partially constructing Step because the step final
    # initialization is done by BuildBot.
    step = chromium_utils.PartiallyInitialize(
        chromium_step.ProcessLogShellStep,
        log_processor_class)

  """
  def  __init__(self, log_processor_class=None, *args, **kwargs):
    """
    Args:
      log_processor_class: subclass of
        process_log.PerformanceLogProcessor that will be initialized and
        invoked once command was successfully completed.
    """
    self._result_text = []
    self._log_processor = None
    # If log_processor_class is not None, it should be a class.  Create an
    # instance of it.
    if log_processor_class:
      self._log_processor = log_processor_class()
    shell.ShellCommand.__init__(self, *args, **kwargs)

  def start(self):
    """Overridden shell.ShellCommand.start method.

    Adds a link for the activity that points to report ULR.
    """

    # got_revision could be poisoned by checking out the script itself.
    # So, let's assume that we will get the exactly the same revision
    # this build has been triggered for, and let the script report
    # the revision it checked out.
    self.setProperty('got_revision', self.getProperty('revision'), 'Source')

    self._CreateReportLinkIfNeccessary()
    shell.ShellCommand.start(self)

  def _GetRevision(self):
    """Returns the revision number for the build.

    Result is the revision number of the latest change that went in
    while doing gclient sync. Tries 'got_revision' (from log parsing)
    then tries 'revision' (usually from forced build). If neither are
    found, will return -1 instead.
    """
    revision = None
    try:
      revision = self.build.getProperty('got_revision')
    except KeyError:
      pass  # 'got_revision' doesn't exist (yet)
    if not revision:
      try:
        revision = self.build.getProperty('revision')
      except KeyError:
        pass  # neither exist
    if not revision:
      revision = -1
    return revision

  def commandComplete(self, cmd):
    """Callback implementation that will use log process to parse 'stdio' data.
    """
    if self._log_processor:
      self._result_text = self._log_processor.Process(
          self._GetRevision(), self.getLog('stdio').getText())

  def getText(self, cmd, results):
    text_list = self.describe(True)
    if self._result_text:
      self._result_text.insert(0, '<div class="BuildResultInfo">')
      self._result_text.append('</div>')
      text_list = text_list + self._result_text
    return text_list

  def evaluateCommand(self, cmd):
    shell_result = shell.ShellCommand.evaluateCommand(self, cmd)
    log_result = None
    if self._log_processor and 'evaluateCommand' in dir(self._log_processor):
      log_result = self._log_processor.evaluateCommand(cmd)
    return BuilderStatus.combine(shell_result, log_result)

  def _CreateReportLinkIfNeccessary(self):
    if self._log_processor and self._log_processor.ReportLink():
      self.addURL('results', "%s" % self._log_processor.ReportLink())


class AnnotationObserver(buildstep.LogLineObserver):
  """This class knows how to understand annotations.

  Here are a list of the currently supported annotations:

  @@@BUILD_STEP <stepname>@@@
  Add a new step <stepname>. End the current step, marking with last available
  status.

  @@@STEP_LINK@<label>@<url>@@@
  Add a link with label <label> linking to <url> to the current stage.

  @@@STEP_WARNINGS@@@
  Mark the current step as having warnings (oragnge).

  @@@STEP_FAILURE@@@
  Mark the current step as having failed (red).

  @@@STEP_EXCEPTION@@@
  Mark the current step as having exceptions (magenta).

  @@@STEP_CLEAR@@@
  Reset the text description of the current step.

  @@@STEP_SUMMARY_CLEAR@@@
  Reset the text summary of the current step.

  @@@STEP_TEXT@<msg>@@@
  Append <msg> to the current step text.

  @@@STEP_SUMMARY_TEXT@<msg>@@@
  Append <msg> to the step summary (appears on top of the waterfall).

  @@@HALT_ON_FAILURE@@@
  Halt if exception or failure steps are encountered (default is not).

  @@@HONOR_ZERO_RETURN_CODE@@@
  Honor the return code being zero (success), even if steps have other results.

  Deprecated annotations:
  TODO(bradnelson): drop these when all users have been tracked down.

  @@@BUILD_WARNINGS@@@
  Equivalent to @@@STEP_WARNINGS@@@

  @@@BUILD_FAILED@@@
  Equivalent to @@@STEP_FAILURE@@@

  @@@BUILD_EXCEPTION@@@
  Equivalent to @@@STEP_EXCEPTION@@@

  @@@link@<label>@<url>@@@
  Equivalent to @@@STEP_LINK@<label>@<url>@@@
  """

  def __init__(self, command=None, *args, **kwargs):
    buildstep.LogLineObserver.__init__(self, *args, **kwargs)
    self.command = command
    self.sections = []
    self.annotate_status = builder.SUCCESS
    self.halt_on_failure = False
    self.honor_zero_return_code = False

  def initialSection(self):
    if self.sections:
      return
    # Add a log section for output before the first section heading.
    log = self.command.addLog('preamble')
    self.sections.append({
        'name': 'preamble',
        'step': self.command.step_status.getBuild().steps[-1],
        'log': log,
        'status': builder.SUCCESS,
        'links': [],
        'step_summary_text': [],
        'step_text': [],
    })

  def fixupLast(self, status=None):
    # Potentially start initial section here, as initial section might have
    # no output at all.
    self.initialSection()

    last = self.sections[-1]
    # Update status if set as an argument.
    if status is not None:
      last['status'] = status
    # Final update of text.
    self.updateText()
    # Add timing info.
    (start, end) = self.command.step_status.getTimes()
    msg = '\n\n' + '-' * 80 + '\n'
    if start is None:
      msg += 'Not Started\n'
    else:
      if end is None:
        end = util.now()
      msg += '\n'.join([
          'started: %s' % time.ctime(start),
          'ended: %s' % time.ctime(end),
          'duration: %s' % util.formatInterval(end - start),
          '',  # So we get a final \n
      ])
    last['log'].addStdout(msg)
    # Change status (unless handling the preamble).
    if len(self.sections) != 1:
      last['step'].stepFinished(last['status'])
    # Finish log.
    last['log'].finish()

  def errLineReceived(self, line):
    self.outLineReceived(line)

  def updateStepStatus(self, status):
    """Update current step status and annotation status based on a new event."""
    self.annotate_status = BuilderStatus.combine(self.annotate_status, status)
    last = self.sections[-1]
    last['status'] = BuilderStatus.combine(last['status'], status)
    if self.halt_on_failure and last['status'] in [
        builder.FAILURE, builder.EXCEPTION]:
      self.fixupLast()
      self.command.finished(last['status'])

  def updateText(self):
    # Don't update the main phase's text.
    if len(self.sections) == 1:
      return

    last = self.sections[-1]

    # Reflect step status in text2.
    if last['status'] == builder.EXCEPTION:
      result = ['exception', last['name']]
    elif last['status'] == builder.FAILURE:
      result = ['failed', last['name']]
    else:
      result = []

    last['step'].setText([last['name']] + last['step_text'])
    last['step'].setText2(result + last['step_summary_text'])

  def outLineReceived(self, line):
    """This is called once with each line of the test log."""
    # Add \n if not there, which seems to be the case for log lines from
    # windows agents, but not others.
    if not line.endswith('\n'):
      line += '\n'
    # Handle initial setup here, as step_status might not exist yet at init.
    self.initialSection()
    # Support: @@@STEP_LINK@<name>@<url>@@@ (emit link)
    # Also support depreceated @@@link@<name>@<url>@@@
    m = re.match('^@@@STEP_LINK@(.*)@(.*)@@@', line)
    if not m:
      m = re.match('^@@@link@(.*)@(.*)@@@', line)
    if m:
      link_label = m.group(1)
      link_url = m.group(2)
      self.sections[-1]['links'].append((link_label, link_url))
      self.sections[-1]['step'].addURL(link_label, link_url)
    # Support: @@@STEP_WARNINGS@@@ (warn on a stage)
    # Also support deprecated @@@BUILD_WARNINGS@@@
    if (line.startswith('@@@STEP_WARNINGS@@@') or
        line.startswith('@@@BUILD_WARNINGS@@@')):
      self.updateStepStatus(builder.WARNINGS)
    # Support: @@@STEP_FAILURE@@@ (fail a stage)
    # Also support deprecated @@@BUILD_FAILED@@@
    if (line.startswith('@@@STEP_FAILURE@@@') or
        line.startswith('@@@BUILD_FAILED@@@')):
      self.updateStepStatus(builder.FAILURE)
    # Support: @@@STEP_EXCEPTION@@@ (exception on a stage)
    # Also support deprecated @@@BUILD_FAILED@@@
    if (line.startswith('@@@STEP_EXCEPTION@@@') or
        line.startswith('@@@BUILD_EXCEPTION@@@')):
      self.updateStepStatus(builder.EXCEPTION)
    # Support: @@@HALT_ON_FAILURE@@@ (halt if a step fails immediately)
    if line.startswith('@@@HALT_ON_FAILURE@@@'):
      self.halt_on_failure = True
    # Support: @@@HONOR_ZERO_RETURN_CODE@@@ (succeed on 0 return, even if some
    #     steps have failed)
    if line.startswith('@@@HONOR_ZERO_RETURN_CODE@@@'):
      self.honor_zero_return_code = True
    # Support: @@@STEP_CLEAR@@@ (reset step description)
    if line.startswith('@@@STEP_CLEAR@@@'):
      self.sections[-1]['step_text'] = []
      self.updateText()
    # Support: @@@STEP_SUMMARY_CLEAR@@@ (reset step summary)
    if line.startswith('@@@STEP_SUMMARY_CLEAR@@@'):
      self.sections[-1]['step_summary_text'] = []
      self.updateText()
    # Support: @@@STEP_TEXT@<msg>@@@
    m = re.match('^@@@STEP_TEXT@(.*)@@@', line)
    if m:
      self.sections[-1]['step_text'].append(m.group(1))
      self.updateText()
    # Support: @@@STEP_SUMMARY_TEXT@<msg>@@@
    m = re.match('^@@@STEP_SUMMARY_TEXT@(.*)@@@', line)
    if m:
      self.sections[-1]['step_summary_text'].append(m.group(1))
      self.updateText()
    # Support: @@@BUILD_STEP <step_name>@@@ (start a new section)
    m = re.match('^@@@BUILD_STEP (.*)@@@', line)
    if m:
      step_name = m.group(1)
      # Ignore duplicate consecutive step labels (for robustness).
      if step_name != self.sections[-1]['name']:
        # Finish up last section.
        self.fixupLast()
        # Add new one.
        step = self.command.step_status.getBuild().addStepWithName(step_name)
        step.stepStarted()
        step.setText([step_name])
        log = step.addLog('stdio')
        self.sections.append({
            'name': step_name,
            'step': step,
            'log': log,
            'status': builder.SUCCESS,
            'links': [],
            'step_summary_text': [],
            'step_text': [],
        })
    # Add to the current secondary log.
    # Doing this last so that @@@BUILD_STEP... occurs in the log of the new
    # step.
    self.sections[-1]['log'].addStdout(line)

  def handleReturnCode(self, return_code):
    # Treat all non-zero return codes as failure.
    # We could have a special return code for warnings/exceptions, however,
    # this might conflict with some existing use of a return code.
    # Besides, applications can always intercept return codes and emit
    # STEP_* tags.
    if return_code == 0:
      self.fixupLast()
      if self.honor_zero_return_code:
        self.annotate_status = builder.SUCCESS
    else:
      self.annotate_status = builder.FAILURE
      self.fixupLast(builder.FAILURE)


class AnnotatedCommand(ProcessLogShellStep):
  """Buildbot command that knows how to display annotations."""

  def __init__(self, *args, **kwargs):
    # Inject standard tags into the environment.
    env = {
        'BUILDBOT_BLAMELIST': WithProperties('%(blamelist:-[])s'),
        'BUILDBOT_BRANCH': WithProperties('%(branch:-None)s'),
        'BUILDBOT_BUILDERNAME': WithProperties('%(buildername:-None)s'),
        'BUILDBOT_BUILDNUMBER': WithProperties('%(buildnumber:-None)s'),
        'BUILDBOT_CLOBBER': WithProperties('%(clobber:+1)s'),
        'BUILDBOT_GOT_REVISION': WithProperties('%(got_revision:-None)s'),
        'BUILDBOT_REVISION': WithProperties('%(revision:-None)s'),
        'BUILDBOT_SCHEDULER': WithProperties('%(scheduler:-None)s'),
        'BUILDBOT_SLAVENAME': WithProperties('%(slavename:-None)s'),
        'BUILDBOT_MSAN_ORIGINS': WithProperties('%(msan_origins:-)s'),
    }
    # Apply the passed in environment on top.
    old_env = kwargs.get('env')
    if not old_env:
      old_env = {}
    env.update(old_env)
    # Change passed in args (ok as a copy is made internally).
    kwargs['env'] = env

    ProcessLogShellStep.__init__(self, *args, **kwargs)
    self.script_observer = AnnotationObserver(self)
    self.addLogObserver('stdio', self.script_observer)

  def interrupt(self, reason):
    self.script_observer.fixupLast(builder.EXCEPTION)
    return ProcessLogShellStep.interrupt(self, reason)

  def evaluateCommand(self, cmd):
    observer_result = self.script_observer.annotate_status
    # Check if ProcessLogShellStep detected a failure or warning also.
    log_processor_result = ProcessLogShellStep.evaluateCommand(self, cmd)
    return BuilderStatus.combine(observer_result, log_processor_result)

  def commandComplete(self, cmd):
    self.script_observer.handleReturnCode(cmd.rc)
    return ProcessLogShellStep.commandComplete(self, cmd)
