# -*- coding: utf-8 -*-
# Copyright 2017 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Contains classes used among bisect modules.

* Score: stores a list of scores and its statistics.
* CommitInfo: stores commit info.
* OptionsChecker: performs sanity check that every required option are given.
"""

from __future__ import division
from __future__ import print_function

import math

from chromite.lib import cros_logging as logging

class Score(object):
  """Stores a list of scores and calculates its statistics.

  Scores can be assigned by constructor or Update().

  Attributes:
    values: A list of scores.
    mean: Mean of the scores.
    variance: Variance of the scores.
    std: Standard deviation of the scores.
  """

  def __init__(self, values=None):
    """Constructor.

    If values is not assigned, e.g. Score(), it returns a default Score object.
    And bool(Score()) == False.

    Args:
      values: A list of scores.
    """
    self.values = []
    self.mean = 0.0
    self.variance = 0.0
    self.std = 0.0
    if values is not None:
      self.Update(values)

  def __repr__(self):
    return 'Score(values=%r)' % self.values

  def __str__(self):
    return 'Score(values=%r, mean=%.3f, var=%.3f, std=%.3f)' % (
        self.values, self.mean, self.variance, self.std)

  def __len__(self):
    """Returns number of scores.

    Returns:
      Number of values.
    """
    return len(self.values)

  def __eq__(self, other):
    return sorted(self.values) == sorted(other.values)

  def __ne__(self, other):
    return not self.__eq__(other)

  def Clear(self):
    """Clears values and statistics."""
    self.values = []
    self.mean = 0.0
    self.variance = 0.0
    self.std = 0.0

  def Update(self, values):
    """Updates scores and their corresponding statistics.

    If values is empty or ill-formed, it calls Clear().

    Args:
      values: a list of scores.
    """
    if not values:
      self.Clear()
      return
    try:
      values = [float(x) for x in values]
    except ValueError as e:
      logging.error('Invalid literal of score: %s', e)
      self.Clear()
      return
    except TypeError:
      logging.error('Invalid type of score: %s', values)
      self.Clear()
      return

    self.values = values
    num_values = len(values)
    if num_values == 1:
      self.mean = values[0]
      self.variance = 0.0
      self.std = 0.0
    else:
      self.mean = sum(values) / num_values
      differences_from_mean = [x - self.mean for x in values]
      squared_differences = [x * x for x in differences_from_mean]
      self.variance = sum(squared_differences) / (num_values - 1)
      self.std = math.sqrt(self.variance)


class CommitInfo(object):
  """Stores commit info.

  Attributes:
    sha1: Commit SHA1.
    title: Commit title.
    score: Evaluation score of the commit.
    label: 'good' or 'bad'.
    timestamp: Commit timestamp.
  """
  def __init__(self, sha1=None, title=None, score=None, label=None,
               timestamp=None):
    """Constructor.

    All arguments are optional. CommitInfo() creates default CommitInfo object
    and bool(CommitInfo()) == False.

    Args:
      sha1: Commit SHA1.
      title: Commit title.
      score: Evaluation score of the commit.
      label: 'good' or 'bad'.
      timestamp: Commit timestamp.
    """
    self.sha1 = '' if sha1 is None else sha1
    self.title = '' if title is None else title
    self.score = Score() if score is None else score
    self.label = '' if label is None else label
    self.timestamp = 0 if timestamp is None else timestamp

  def __repr__(self):
    return 'CommitInfo(sha1=%r, title=%r, score=%r, label=%r, timestamp=%r)' % (
        self.sha1, self.title, self.score, self.label, self.timestamp)

  def __eq__(self, other):
    return (self.sha1 == other.sha1 and self.title == other.title and
            self.score == other.score and self.label == other.label and
            self.timestamp == other.timestamp)

  def __ne__(self, other):
    return not self.__eq__(other)

  def __bool__(self):
    return bool(self.sha1 or self.timestamp or self.title or self.label or
                self.score)

  # Python 2 glue.
  __nonzero__ = __bool__


class MissingRequiredOptionsException(Exception):
  """Exception raised for missing required options."""


class OptionsChecker(object):
  """Makes sure that __init__'s 'options' contains all required arguments.

  Its derived class should just update class attribute "REQUIRED_ARGS" and
  invokes __init__ to get options checked. For example:
    class ClassA(OptionsChecker):
      REQUIRED_ARGS = ['a']
      def __init__(self, options):
        super(ClassA, self).__init__(options)

    class ClassB(ClassA):
      REQUIRED_ARGS = ClassA.REQUIRED_ARGS + ['b']
      def __init__(self, options):
        super(ClassB, self).__init__(options)

    then calling
      ClassA(argparse.Namespace(a='a'))
      ClassB(argparse.Namespace(a='a', b='b'))
    is okay, but calling
      ClassA(argparse.Namespace(c='c'))
      ClassB(argparse.Namespace(b='b'))
    raises MissingRequiredOptionsException telling you that argument a is
    missing.
  """
  REQUIRED_ARGS = ()

  def __init__(self, options):
    """Constructor.

    Args:
      options: An argparse.Namespace to hold command line arguments.

    Raises:
      MissingRequiredOptionsException if any required argument is missing.
    """
    self.SanityCheckOptions(options)

  @classmethod
  def SanityCheckOptions(cls, options):
    """Performs sanity check on command line arguments.

    Args:
      options: An argparse.Namespace to hold command line arguments.

    Returns:
      True if sanity check passed.

    Raises:
      MissingRequiredOptionsException if any required argument is missing.
    """
    missing_args = [arg for arg in cls.REQUIRED_ARGS if arg not in options]
    if missing_args:
      raise MissingRequiredOptionsException(
          'Missing command line argument(s) %s required for class %s' %
          (missing_args, cls.__name__))
    return True
