# Copyright 2017 The PDFium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Classes that draw conclusions out of a comparison and represent them."""

from __future__ import print_function

from collections import Counter

FORMAT_RED = '\033[01;31m{0}\033[00m'
FORMAT_GREEN = '\033[01;32m{0}\033[00m'
FORMAT_MAGENTA = '\033[01;35m{0}\033[00m'
FORMAT_CYAN = '\033[01;36m{0}\033[00m'
FORMAT_NORMAL = '{0}'

RATING_FAILURE = 'failure'
RATING_REGRESSION = 'regression'
RATING_IMPROVEMENT = 'improvement'
RATING_NO_CHANGE = 'no_change'
RATING_SMALL_CHANGE = 'small_change'

RATINGS = [
    RATING_FAILURE, RATING_REGRESSION, RATING_IMPROVEMENT, RATING_NO_CHANGE,
    RATING_SMALL_CHANGE
]

RATING_TO_COLOR = {
    RATING_FAILURE: FORMAT_MAGENTA,
    RATING_REGRESSION: FORMAT_RED,
    RATING_IMPROVEMENT: FORMAT_CYAN,
    RATING_NO_CHANGE: FORMAT_GREEN,
    RATING_SMALL_CHANGE: FORMAT_NORMAL,
}


class ComparisonConclusions(object):
  """All conclusions drawn from a comparison.

  This is initialized empty and then processes pairs of results for each test
  case, determining the rating for that case, which can be:
  "failure" if either or both runs for the case failed.
  "regression" if there is a significant increase in time for the test case.
  "improvement" if there is a significant decrease in time for the test case.
  "no_change" if the time for the test case did not change at all.
  "small_change" if the time for the test case changed but within the threshold.
  """

  def __init__(self, threshold_significant):
    """Initializes an empty ComparisonConclusions.

    Args:
      threshold_significant: Float with the tolerance beyond which changes in
          measurements are considered significant.

          The change is considered as a multiplication rather than an addition
          of a fraction of the previous measurement, that is, a
          threshold_significant of 1.0 will flag test cases that became over
          100% slower (> 200% of the previous time measured) or over 100% faster
          (< 50% of the previous time measured).

          threshold_significant 0.02 -> 98.04% to 102% is not significant
          threshold_significant 0.1 -> 90.9% to 110% is not significant
          threshold_significant 0.25 -> 80% to 125% is not significant
          threshold_significant 1 -> 50% to 200% is not significant
          threshold_significant 4 -> 20% to 500% is not significant

    """
    self.threshold_significant = threshold_significant
    self.threshold_significant_negative = (1 / (1 + threshold_significant)) - 1

    self.params = {'threshold': threshold_significant}
    self.summary = ComparisonSummary()
    self.case_results = {}

  def ProcessCase(self, case_name, before, after):
    """Feeds a test case results to the ComparisonConclusions.

    Args:
      case_name: String identifying the case.
      before: Measurement for the "before" version of the code.
      after: Measurement for the "after" version of the code.
    """

    # Switch 0 to None to simplify the json dict output. All zeros are
    # considered failed runs, so they will be represented by "null".
    if not before:
      before = None
    if not after:
      after = None

    if not before or not after:
      ratio = None
      rating = RATING_FAILURE
    else:
      ratio = (float(after) / before) - 1.0
      if ratio > self.threshold_significant:
        rating = RATING_REGRESSION
      elif ratio < self.threshold_significant_negative:
        rating = RATING_IMPROVEMENT
      elif ratio == 0:
        rating = RATING_NO_CHANGE
      else:
        rating = RATING_SMALL_CHANGE

    case_result = CaseResult(case_name, before, after, ratio, rating)

    self.summary.ProcessCaseResult(case_result)
    self.case_results[case_name] = case_result

  def GetSummary(self):
    """Gets the ComparisonSummary with consolidated totals."""
    return self.summary

  def GetCaseResults(self):
    """Gets a dict mapping each test case identifier to its CaseResult."""
    return self.case_results

  def GetOutputDict(self):
    """Returns a conclusions dict with all the conclusions drawn.

    Returns:
      A serializable dict with the format illustrated below:
      {
        "version": 1,
        "params": {
          "threshold": 0.02
        },
        "summary": {
          "total": 123,
          "failure": 1,
          "regression": 2,
          "improvement": 1,
          "no_change": 100,
          "small_change": 19
        },
        "comparison_by_case": {
          "testing/resources/new_test.pdf": {
            "before": None,
            "after": 1000,
            "ratio": None,
            "rating": "failure"
          },
          "testing/resources/test1.pdf": {
            "before": 100,
            "after": 120,
            "ratio": 0.2,
            "rating": "regression"
          },
          "testing/resources/test2.pdf": {
            "before": 100,
            "after": 2000,
            "ratio": 19.0,
            "rating": "regression"
          },
          "testing/resources/test3.pdf": {
            "before": 1000,
            "after": 1005,
            "ratio": 0.005,
            "rating": "small_change"
          },
          "testing/resources/test4.pdf": {
            "before": 1000,
            "after": 1000,
            "ratio": 0.0,
            "rating": "no_change"
          },
          "testing/resources/test5.pdf": {
            "before": 1000,
            "after": 600,
            "ratio": -0.4,
            "rating": "improvement"
          }
        }
      }
    """
    output_dict = {}
    output_dict['version'] = 1
    output_dict['params'] = {'threshold': self.threshold_significant}
    output_dict['summary'] = self.summary.GetOutputDict()
    output_dict['comparison_by_case'] = {
        cr.case_name.decode('utf-8'): cr.GetOutputDict()
        for cr in self.GetCaseResults().values()
    }
    return output_dict


class ComparisonSummary(object):
  """Totals computed for a comparison."""

  def __init__(self):
    self.rating_counter = Counter()

  def ProcessCaseResult(self, case_result):
    self.rating_counter[case_result.rating] += 1

  def GetTotal(self):
    """Gets the number of test cases processed."""
    return sum(self.rating_counter.values())

  def GetCount(self, rating):
    """Gets the number of test cases processed with a given rating."""
    return self.rating_counter[rating]

  def GetOutputDict(self):
    """Returns a dict that can be serialized with all the totals."""
    result = {'total': self.GetTotal()}
    for rating in RATINGS:
      result[rating] = self.GetCount(rating)
    return result


class CaseResult(object):
  """The conclusion for the comparison of a single test case."""

  def __init__(self, case_name, before, after, ratio, rating):
    """Initializes an empty ComparisonConclusions.

    Args:
      case_name: String identifying the case.
      before: Measurement for the "before" version of the code.
      after: Measurement for the "after" version of the code.
      ratio: Difference between |after| and |before| as a fraction of |before|.
      rating: Rating for this test case.
    """
    self.case_name = case_name
    self.before = before
    self.after = after
    self.ratio = ratio
    self.rating = rating

  def GetOutputDict(self):
    """Returns a dict with the test case's conclusions."""
    return {
        'before': self.before,
        'after': self.after,
        'ratio': self.ratio,
        'rating': self.rating
    }


def PrintConclusionsDictHumanReadable(conclusions_dict, colored, key=None):
  """Prints a conclusions dict in a human-readable way.

  Args:
    conclusions_dict: Dict to print.
    colored: Whether to color the output to highlight significant changes.
    key: String with the CaseResult dictionary key to sort the cases.
  """
  # Print header
  print('=' * 80)
  print('{0:>11s} {1:>15s}  {2}'.format('% Change', 'Time after', 'Test case'))
  print('-' * 80)

  color = FORMAT_NORMAL

  # Print cases
  if key is not None:
    case_pairs = sorted(
        conclusions_dict['comparison_by_case'].iteritems(),
        key=lambda kv: kv[1][key])
  else:
    case_pairs = sorted(conclusions_dict['comparison_by_case'].iteritems())

  for case_name, case_dict in case_pairs:
    if colored:
      color = RATING_TO_COLOR[case_dict['rating']]

    if case_dict['rating'] == RATING_FAILURE:
      print(u'{} to measure time for {}'.format(
          color.format('Failed'), case_name).encode('utf-8'))
      continue

    print(u'{0} {1:15,d}  {2}'.format(
        color.format('{:+11.4%}'.format(case_dict['ratio'])),
        case_dict['after'], case_name).encode('utf-8'))

  # Print totals
  totals = conclusions_dict['summary']
  print('=' * 80)
  print('Test cases run: %d' % totals['total'])

  if colored:
    color = FORMAT_MAGENTA if totals[RATING_FAILURE] else FORMAT_GREEN
  print('Failed to measure: %s' % color.format(totals[RATING_FAILURE]))

  if colored:
    color = FORMAT_RED if totals[RATING_REGRESSION] else FORMAT_GREEN
  print('Regressions: %s' % color.format(totals[RATING_REGRESSION]))

  if colored:
    color = FORMAT_CYAN if totals[RATING_IMPROVEMENT] else FORMAT_GREEN
  print('Improvements: %s' % color.format(totals[RATING_IMPROVEMENT]))
