#!/usr/bin/env python
# Copyright (c) 2012 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 file.

"""Get rietveld stats about the review you done, or forgot to do.

Example:
  - my_reviews.py -r me@chromium.org -Q  for stats for last quarter.
"""
import datetime
import math
import optparse
import os
import sys

import auth
import rietveld


def username(email):
  """Keeps the username of an email address."""
  return email.split('@', 1)[0]


def to_datetime(string):
  """Load UTC time as a string into a datetime object."""
  try:
    # Format is 2011-07-05 01:26:12.084316
    return datetime.datetime.strptime(
        string.split('.', 1)[0], '%Y-%m-%d %H:%M:%S')
  except ValueError:
    return datetime.datetime.strptime(string, '%Y-%m-%d')


def to_time(seconds):
  """Convert a number of seconds into human readable compact string."""
  prefix = ''
  if seconds < 0:
    prefix = '-'
    seconds *= -1
  minutes = math.floor(seconds / 60)
  seconds -= minutes * 60
  hours = math.floor(minutes / 60)
  minutes -= hours * 60
  days = math.floor(hours / 24)
  hours -= days * 24
  out = []
  if days > 0:
    out.append('%dd' % days)
  if hours > 0 or days > 0:
    out.append('%02dh' % hours)
  if minutes > 0 or hours > 0 or days > 0:
    out.append('%02dm' % minutes)
  if seconds > 0 and not out:
    # Skip seconds unless there's only seconds.
    out.append('%02ds' % seconds)
  return prefix + ''.join(out)


class Stats(object):
  def __init__(self):
    self.total = 0
    self.actually_reviewed = 0
    self.latencies = []
    self.lgtms = 0
    self.multiple_lgtms = 0
    self.drive_by = 0
    self.not_requested = 0
    self.self_review = 0

    self.percent_lgtm = 0.
    self.percent_drive_by = 0.
    self.percent_not_requested = 0.
    self.days = 0

  @property
  def average_latency(self):
    if not self.latencies:
      return 0
    return sum(self.latencies) / float(len(self.latencies))

  @property
  def median_latency(self):
    if not self.latencies:
      return 0
    length = len(self.latencies)
    latencies = sorted(self.latencies)
    if (length & 1) == 0:
      return (latencies[length/2] + latencies[length/2-1]) / 2.
    else:
      return latencies[length/2]

  @property
  def percent_done(self):
    if not self.total:
      return 0
    return self.actually_reviewed * 100. / self.total

  @property
  def review_per_day(self):
    if not self.days:
      return 0
    return self.total * 1. / self.days

  @property
  def review_done_per_day(self):
    if not self.days:
      return 0
    return self.actually_reviewed * 1. / self.days

  def finalize(self, first_day, last_day):
    if self.actually_reviewed:
      assert self.actually_reviewed > 0
      self.percent_lgtm = (self.lgtms * 100. / self.actually_reviewed)
      self.percent_drive_by = (self.drive_by * 100. / self.actually_reviewed)
      self.percent_not_requested = (
          self.not_requested * 100. / self.actually_reviewed)
    assert bool(first_day) == bool(last_day)
    if first_day and last_day:
      assert first_day <= last_day
      self.days = (to_datetime(last_day) - to_datetime(first_day)).days + 1
      assert self.days > 0


def _process_issue_lgtms(issue, reviewer, stats):
  """Calculates LGTMs stats."""
  stats.actually_reviewed += 1
  reviewer_lgtms = len([
    msg for msg in issue['messages']
    if msg['approval'] and msg['sender'] == reviewer])
  if reviewer_lgtms > 1:
    stats.multiple_lgtms += 1
    return ' X '
  if reviewer_lgtms:
    stats.lgtms += 1
    return ' x '
  else:
    return ' o '


def _process_issue_latency(issue, reviewer, stats):
  """Calculates latency for an issue that was actually reviewed."""
  from_owner = [
    msg for msg in issue['messages'] if msg['sender'] == issue['owner_email']
  ]
  if not from_owner:
    # Probably requested by email.
    stats.not_requested += 1
    return '<no rqst sent>'

  first_msg_from_owner = None
  latency = None
  received = False
  for index, msg in enumerate(issue['messages']):
    if not first_msg_from_owner and msg['sender'] == issue['owner_email']:
      first_msg_from_owner = msg
    if index and not received and msg['sender'] == reviewer:
      # Not first email, reviewer never received one, reviewer sent a mesage.
      stats.drive_by += 1
      return '<drive-by>'
    received |= reviewer in msg['recipients']

    if first_msg_from_owner and msg['sender'] == reviewer:
      delta = msg['date'] - first_msg_from_owner['date']
      latency = delta.seconds + delta.days * 24 * 3600
      break

  if latency is None:
    stats.not_requested += 1
    return '<no rqst sent>'
  if latency > 0:
    stats.latencies.append(latency)
  else:
    stats.not_requested += 1
  return to_time(latency)


def _process_issue(issue):
  """Preprocesses the issue to simplify the remaining code."""
  issue['owner_email'] = username(issue['owner_email'])
  issue['reviewers'] = set(username(r) for r in issue['reviewers'])
  # By default, hide commit-bot.
  issue['reviewers'] -= set(['commit-bot'])
  for msg in issue['messages']:
    msg['sender'] = username(msg['sender'])
    msg['recipients'] = [username(r) for r in msg['recipients']]
    # Convert all times to datetime instances.
    msg['date'] = to_datetime(msg['date'])
  issue['messages'].sort(key=lambda x: x['date'])


def print_issue(issue, reviewer, stats):
  """Process an issue and prints stats about it."""
  stats.total += 1
  _process_issue(issue)
  if issue['owner_email'] == reviewer:
    stats.self_review += 1
    latency = '<self review>'
    reviewed = ''
  elif any(msg['sender'] == reviewer for msg in issue['messages']):
    reviewed = _process_issue_lgtms(issue, reviewer, stats)
    latency = _process_issue_latency(issue, reviewer, stats)
  else:
    latency = 'N/A'
    reviewed = ''

  # More information is available, print issue.keys() to see them.
  print '%7d %10s %3s %14s %-15s  %s' % (
      issue['issue'],
      issue['created'][:10],
      reviewed,
      latency,
      issue['owner_email'],
      ', '.join(sorted(issue['reviewers'])))


def print_reviews(
    reviewer, created_after, created_before, instance_url, auth_config):
  """Prints issues |reviewer| received and potentially reviewed."""
  remote = rietveld.Rietveld(instance_url, auth_config)

  # The stats we gather. Feel free to send me a CL to get more stats.
  stats = Stats()

  # Column sizes need to match print_issue() output.
  print >> sys.stderr, (
      'Issue   Creation   Did         Latency Owner           Reviewers')

  # See def search() in rietveld.py to see all the filters you can use.
  issues = []
  for issue in remote.search(
      reviewer=reviewer,
      created_after=created_after,
      created_before=created_before,
      with_messages=True):
    issues.append(issue)
    print_issue(issue, username(reviewer), stats)

  issues.sort(key=lambda x: x['created'])
  first_day = None
  last_day = None
  if issues:
    first_day = issues[0]['created'][:10]
    last_day = issues[-1]['created'][:10]
  stats.finalize(first_day, last_day)

  print >> sys.stderr, (
      '%s reviewed %d issues out of %d (%1.1f%%). %d were self-review.' %
      (reviewer, stats.actually_reviewed, stats.total, stats.percent_done,
        stats.self_review))
  print >> sys.stderr, (
      '%4.1f review request/day during %3d days   (%4.1f r/d done).' % (
      stats.review_per_day, stats.days, stats.review_done_per_day))
  print >> sys.stderr, (
      '%4d were drive-bys                       (%5.1f%% of reviews done).' % (
        stats.drive_by, stats.percent_drive_by))
  print >> sys.stderr, (
      '%4d were requested over IM or irc        (%5.1f%% of reviews done).' % (
        stats.not_requested, stats.percent_not_requested))
  print >> sys.stderr, (
      ('%4d issues LGTM\'d                        (%5.1f%% of reviews done),'
       ' gave multiple LGTMs on %d issues.') % (
      stats.lgtms, stats.percent_lgtm, stats.multiple_lgtms))
  print >> sys.stderr, (
      'Average latency from request to first comment is %s.' %
      to_time(stats.average_latency))
  print >> sys.stderr, (
      'Median latency from request to first comment is %s.' %
      to_time(stats.median_latency))


def print_count(
    reviewer, created_after, created_before, instance_url, auth_config):
  remote = rietveld.Rietveld(instance_url, auth_config)
  print len(list(remote.search(
      reviewer=reviewer,
      created_after=created_after,
      created_before=created_before,
      keys_only=True)))


def get_previous_quarter(today):
  """There are four quarters, 01-03, 04-06, 07-09, 10-12.

  If today is in the last month of a quarter, assume it's the current quarter
  that is requested.
  """
  end_year = today.year
  end_month = today.month - (today.month % 3) + 1
  if end_month <= 0:
    end_year -= 1
    end_month += 12
  if end_month > 12:
    end_year += 1
    end_month -= 12
  end = '%d-%02d-01' % (end_year, end_month)
  begin_year = end_year
  begin_month = end_month - 3
  if begin_month <= 0:
    begin_year -= 1
    begin_month += 12
  begin = '%d-%02d-01' % (begin_year, begin_month)
  return begin, end


def main():
  # Silence upload.py.
  rietveld.upload.verbosity = 0
  today = datetime.date.today()
  begin, end = get_previous_quarter(today)
  default_email = os.environ.get('EMAIL_ADDRESS')
  if not default_email:
    user = os.environ.get('USER')
    if user:
      default_email = user + '@chromium.org'

  parser = optparse.OptionParser(description=__doc__)
  parser.add_option(
      '--count', action='store_true',
      help='Just count instead of printing individual issues')
  parser.add_option(
      '-r', '--reviewer', metavar='<email>', default=default_email,
      help='Filter on issue reviewer, default=%default')
  parser.add_option(
      '-b', '--begin', metavar='<date>',
      help='Filter issues created after the date')
  parser.add_option(
      '-e', '--end', metavar='<date>',
      help='Filter issues created before the date')
  parser.add_option(
      '-Q', '--last_quarter', action='store_true',
      help='Use last quarter\'s dates, e.g. %s to %s' % (begin, end))
  parser.add_option(
      '-i', '--instance_url', metavar='<host>',
      default='http://codereview.chromium.org',
      help='Host to use, default is %default')
  auth.add_auth_options(parser)
  # Remove description formatting
  parser.format_description = (
      lambda _: parser.description)  # pylint: disable=E1101
  options, args = parser.parse_args()
  auth_config = auth.extract_auth_config_from_options(options)
  if args:
    parser.error('Args unsupported')
  if options.reviewer is None:
    parser.error('$EMAIL_ADDRESS and $USER are not set, please use -r')

  print >> sys.stderr, 'Searching for reviews by %s' % options.reviewer
  if options.last_quarter:
    options.begin = begin
    options.end = end
    print >> sys.stderr, 'Using range %s to %s' % (
        options.begin, options.end)
  else:
    if options.begin is None or options.end is None:
      parser.error('Please specify either --last_quarter or --begin and --end')

  # Validate dates.
  try:
    to_datetime(options.begin)
    to_datetime(options.end)
  except ValueError as e:
    parser.error('%s: %s - %s' % (e, options.begin, options.end))

  if options.count:
    print_count(
        options.reviewer,
        options.begin,
        options.end,
        options.instance_url,
        auth_config)
  else:
    print_reviews(
        options.reviewer,
        options.begin,
        options.end,
        options.instance_url,
        auth_config)
  return 0


if __name__ == '__main__':
  try:
    sys.exit(main())
  except KeyboardInterrupt:
    sys.stderr.write('interrupted\n')
    sys.exit(1)
