#!/usr/bin/env vpython3
# 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 stats about your activity.

Example:
  - my_activity.py  for stats for the current week (last week on mondays).
  - my_activity.py -Q  for stats for last quarter.
  - my_activity.py -Y  for stats for this year.
  - my_activity.py -b 4/24/19  for stats since April 24th 2019.
  - my_activity.py -b 4/24/19 -e 6/16/19 stats between April 24th and June 16th.
  - my_activity.py -jd to output stats for the week to json with deltas data.
"""

# These services typically only provide a created time and a last modified time
# for each item for general queries. This is not enough to determine if there
# was activity in a given time period. So, we first query for all things created
# before end and modified after begin. Then, we get the details of each item and
# check those details to determine if there was activity in the given period.
# This means that query time scales mostly with (today() - begin).

from __future__ import print_function

import collections
import contextlib
from datetime import datetime
from datetime import timedelta
import httplib2
import itertools
import json
import logging
from multiprocessing.pool import ThreadPool
import optparse
import os
import subprocess
from string import Formatter
import sys
import urllib
import re

import auth
import fix_encoding
import gclient_utils
import gerrit_util


if sys.version_info.major == 2:
  logging.warning(
      'Python 2 is deprecated. Run my_activity.py using vpython3.')
  import urllib as urllib_parse
else:
  import urllib.parse as urllib_parse

try:
  import dateutil  # pylint: disable=import-error
  import dateutil.parser
  from dateutil.relativedelta import relativedelta
except ImportError:
  logging.error('python-dateutil package required')
  exit(1)


class DefaultFormatter(Formatter):
  def __init__(self, default = ''):
    super(DefaultFormatter, self).__init__()
    self.default = default

  def get_value(self, key, args, kwds):
    if isinstance(key, str) and key not in kwds:
      return self.default
    return Formatter.get_value(self, key, args, kwds)

gerrit_instances = [
  {
    'url': 'android-review.googlesource.com',
    'shorturl': 'r.android.com',
    'short_url_protocol': 'https',
  },
  {
    'url': 'gerrit-review.googlesource.com',
  },
  {
    'url': 'chrome-internal-review.googlesource.com',
    'shorturl': 'crrev.com/i',
    'short_url_protocol': 'https',
  },
  {
    'url': 'chromium-review.googlesource.com',
    'shorturl': 'crrev.com/c',
    'short_url_protocol': 'https',
  },
  {
    'url': 'dawn-review.googlesource.com',
  },
  {
    'url': 'pdfium-review.googlesource.com',
  },
  {
    'url': 'skia-review.googlesource.com',
  },
]

monorail_projects = {
  'angleproject': {
    'shorturl': 'anglebug.com',
    'short_url_protocol': 'http',
  },
  'chromium': {
    'shorturl': 'crbug.com',
    'short_url_protocol': 'https',
  },
  'dawn': {},
  'google-breakpad': {},
  'gyp': {},
  'pdfium': {
    'shorturl': 'crbug.com/pdfium',
    'short_url_protocol': 'https',
  },
  'skia': {},
  'v8': {
    'shorturl': 'crbug.com/v8',
    'short_url_protocol': 'https',
  },
}

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


def datetime_to_midnight(date):
  return date - timedelta(hours=date.hour, minutes=date.minute,
                          seconds=date.second, microseconds=date.microsecond)


def get_quarter_of(date):
  begin = (datetime_to_midnight(date) -
           relativedelta(months=(date.month - 1) % 3, days=(date.day - 1)))
  return begin, begin + relativedelta(months=3)


def get_year_of(date):
  begin = (datetime_to_midnight(date) -
           relativedelta(months=(date.month - 1), days=(date.day - 1)))
  return begin, begin + relativedelta(years=1)


def get_week_of(date):
  begin = (datetime_to_midnight(date) - timedelta(days=date.weekday()))
  return begin, begin + timedelta(days=7)


def get_yes_or_no(msg):
  while True:
    response = gclient_utils.AskForData(msg + ' yes/no [no] ')
    if response == 'y' or response == 'yes':
      return True
    elif not response or response == 'n' or response == 'no':
      return False


def datetime_from_gerrit(date_string):
  return datetime.strptime(date_string, '%Y-%m-%d %H:%M:%S.%f000')


def datetime_from_monorail(date_string):
  return datetime.strptime(date_string, '%Y-%m-%dT%H:%M:%S')

def extract_bug_numbers_from_description(issue):
  # Getting the description for REST Gerrit
  revision = issue['revisions'][issue['current_revision']]
  description = revision['commit']['message']

  bugs = []
  # Handle both "Bug: 99999" and "BUG=99999" bug notations
  # Multiple bugs can be noted on a single line or in multiple ones.
  matches = re.findall(
      r'^(BUG=|(Bug|Fixed):\s*)((((?:[a-zA-Z0-9-]+:)?\d+)(,\s?)?)+)',
      description, flags=re.IGNORECASE | re.MULTILINE)
  if matches:
    for match in matches:
      bugs.extend(match[2].replace(' ', '').split(','))
    # Add default chromium: prefix if none specified.
    bugs = [bug if ':' in bug else 'chromium:%s' % bug for bug in bugs]

  return sorted(set(bugs))

class MyActivity(object):
  def __init__(self, options):
    self.options = options
    self.modified_after = options.begin
    self.modified_before = options.end
    self.user = options.user
    self.changes = []
    self.reviews = []
    self.issues = []
    self.referenced_issues = []
    self.google_code_auth_token = None
    self.access_errors = set()
    self.skip_servers = (options.skip_servers.split(','))

  def show_progress(self, how='.'):
    if sys.stdout.isatty():
      sys.stdout.write(how)
      sys.stdout.flush()

  def gerrit_changes_over_rest(self, instance, filters):
    # Convert the "key:value" filter to a list of (key, value) pairs.
    req = list(f.split(':', 1) for f in filters)
    try:
      # Instantiate the generator to force all the requests now and catch the
      # errors here.
      return list(gerrit_util.GenerateAllChanges(instance['url'], req,
          o_params=['MESSAGES', 'LABELS', 'DETAILED_ACCOUNTS',
                    'CURRENT_REVISION', 'CURRENT_COMMIT']))
    except gerrit_util.GerritError as e:
      error_message = 'Looking up %r: %s' % (instance['url'], e)
      if error_message not in self.access_errors:
        self.access_errors.add(error_message)
      return []

  def gerrit_search(self, instance, owner=None, reviewer=None):
    if instance['url'] in self.skip_servers:
      return []
    max_age = datetime.today() - self.modified_after
    filters = ['-age:%ss' % (max_age.days * 24 * 3600 + max_age.seconds)]
    if owner:
      assert not reviewer
      filters.append('owner:%s' % owner)
    else:
      filters.extend(('-owner:%s' % reviewer, 'reviewer:%s' % reviewer))
    # TODO(cjhopman): Should abandoned changes be filtered out when
    # merged_only is not enabled?
    if self.options.merged_only:
      filters.append('status:merged')

    issues = self.gerrit_changes_over_rest(instance, filters)
    self.show_progress()
    issues = [self.process_gerrit_issue(instance, issue)
              for issue in issues]

    issues = filter(self.filter_issue, issues)
    issues = sorted(issues, key=lambda i: i['modified'], reverse=True)

    return issues

  def process_gerrit_issue(self, instance, issue):
    ret = {}
    if self.options.deltas:
      ret['delta'] = DefaultFormatter().format(
          '+{insertions},-{deletions}',
          **issue)
    ret['status'] = issue['status']
    if 'shorturl' in instance:
      protocol = instance.get('short_url_protocol', 'http')
      url = instance['shorturl']
    else:
      protocol = 'https'
      url = instance['url']
    ret['review_url'] = '%s://%s/%s' % (protocol, url, issue['_number'])

    ret['header'] = issue['subject']
    ret['owner'] = issue['owner'].get('email', '')
    ret['author'] = ret['owner']
    ret['created'] = datetime_from_gerrit(issue['created'])
    ret['modified'] = datetime_from_gerrit(issue['updated'])
    if 'messages' in issue:
      ret['replies'] = self.process_gerrit_issue_replies(issue['messages'])
    else:
      ret['replies'] = []
    ret['reviewers'] = set(r['author'] for r in ret['replies'])
    ret['reviewers'].discard(ret['author'])
    ret['bugs'] = extract_bug_numbers_from_description(issue)
    return ret

  @staticmethod
  def process_gerrit_issue_replies(replies):
    ret = []
    replies = filter(lambda r: 'author' in r and 'email' in r['author'],
        replies)
    for reply in replies:
      ret.append({
        'author': reply['author']['email'],
        'created': datetime_from_gerrit(reply['date']),
        'content': reply['message'],
      })
    return ret

  def monorail_get_auth_http(self):
    # Manually use a long timeout (10m); for some users who have a
    # long history on the issue tracker, whatever the default timeout
    # is is reached.
    return auth.Authenticator().authorize(httplib2.Http(timeout=600))

  def filter_modified_monorail_issue(self, issue):
    """Precisely checks if an issue has been modified in the time range.

    This fetches all issue comments to check if the issue has been modified in
    the time range specified by user. This is needed because monorail only
    allows filtering by last updated and published dates, which is not
    sufficient to tell whether a given issue has been modified at some specific
    time range. Any update to the issue is a reported as comment on Monorail.

    Args:
      issue: Issue dict as returned by monorail_query_issues method. In
          particular, must have a key 'uid' formatted as 'project:issue_id'.

    Returns:
      Passed issue if modified, None otherwise.
    """
    http = self.monorail_get_auth_http()
    project, issue_id = issue['uid'].split(':')
    url = ('https://monorail-prod.appspot.com/_ah/api/monorail/v1/projects'
           '/%s/issues/%s/comments?maxResults=10000') % (project, issue_id)
    _, body = http.request(url)
    self.show_progress()
    content = json.loads(body)
    if not content:
      logging.error('Unable to parse %s response from monorail.', project)
      return issue

    for item in content.get('items', []):
      comment_published = datetime_from_monorail(item['published'])
      if self.filter_modified(comment_published):
        return issue

    return None

  def monorail_query_issues(self, project, query):
    http = self.monorail_get_auth_http()
    url = ('https://monorail-prod.appspot.com/_ah/api/monorail/v1/projects'
           '/%s/issues') % project
    query_data = urllib_parse.urlencode(query)
    url = url + '?' + query_data
    _, body = http.request(url)
    self.show_progress()
    content = json.loads(body)
    if not content:
      logging.error('Unable to parse %s response from monorail.', project)
      return []

    issues = []
    project_config = monorail_projects.get(project, {})
    for item in content.get('items', []):
      if project_config.get('shorturl'):
        protocol = project_config.get('short_url_protocol', 'http')
        item_url = '%s://%s/%d' % (
            protocol, project_config['shorturl'], item['id'])
      else:
        item_url = 'https://bugs.chromium.org/p/%s/issues/detail?id=%d' % (
            project, item['id'])
      issue = {
        'uid': '%s:%s' % (project, item['id']),
        'header': item['title'],
        'created': datetime_from_monorail(item['published']),
        'modified': datetime_from_monorail(item['updated']),
        'author': item['author']['name'],
        'url': item_url,
        'comments': [],
        'status': item['status'],
        'labels': [],
        'components': []
      }
      if 'owner' in item:
        issue['owner'] = item['owner']['name']
      else:
        issue['owner'] = 'None'
      if 'labels' in item:
        issue['labels'] = item['labels']
      if 'components' in item:
        issue['components'] = item['components']
      issues.append(issue)

    return issues

  def monorail_issue_search(self, project):
    epoch = datetime.utcfromtimestamp(0)
    # Defaults to @chromium.org email if one wasn't provided on -u option.
    user_str = (self.options.email if self.options.email.find('@') >= 0
                else '%s@chromium.org' % self.user)

    issues = self.monorail_query_issues(project, {
      'maxResults': 10000,
      'q': user_str,
      'publishedMax': '%d' % (self.modified_before - epoch).total_seconds(),
      'updatedMin': '%d' % (self.modified_after - epoch).total_seconds(),
    })

    if self.options.completed_issues:
      return [
          issue for issue in issues
          if (self.match(issue['owner']) and
              issue['status'].lower() in ('verified', 'fixed'))
      ]

    return [
        issue for issue in issues
        if issue['author'] == user_str or issue['owner'] == user_str]

  def monorail_get_issues(self, project, issue_ids):
    return self.monorail_query_issues(project, {
      'maxResults': 10000,
      'q': 'id:%s' % ','.join(issue_ids)
    })

  def print_heading(self, heading):
    print()
    print(self.options.output_format_heading.format(heading=heading))

  def match(self, author):
    if '@' in self.user:
      return author == self.user
    return author.startswith(self.user + '@')

  def print_change(self, change):
    activity = len([
        reply
        for reply in change['replies']
        if self.match(reply['author'])
    ])
    optional_values = {
        'created': change['created'].date().isoformat(),
        'modified': change['modified'].date().isoformat(),
        'reviewers': ', '.join(change['reviewers']),
        'status': change['status'],
        'activity': activity,
    }
    if self.options.deltas:
      optional_values['delta'] = change['delta']

    self.print_generic(self.options.output_format,
                       self.options.output_format_changes,
                       change['header'],
                       change['review_url'],
                       change['author'],
                       change['created'],
                       change['modified'],
                       optional_values)

  def print_issue(self, issue):
    optional_values = {
        'created': issue['created'].date().isoformat(),
        'modified': issue['modified'].date().isoformat(),
        'owner': issue['owner'],
        'status': issue['status'],
    }
    self.print_generic(self.options.output_format,
                       self.options.output_format_issues,
                       issue['header'],
                       issue['url'],
                       issue['author'],
                       issue['created'],
                       issue['modified'],
                       optional_values)

  def print_review(self, review):
    activity = len([
        reply
        for reply in review['replies']
        if self.match(reply['author'])
    ])
    optional_values = {
        'created': review['created'].date().isoformat(),
        'modified': review['modified'].date().isoformat(),
        'status': review['status'],
        'activity': activity,
    }
    if self.options.deltas:
      optional_values['delta'] = review['delta']

    self.print_generic(self.options.output_format,
                       self.options.output_format_reviews,
                       review['header'],
                       review['review_url'],
                       review['author'],
                       review['created'],
                       review['modified'],
                       optional_values)

  @staticmethod
  def print_generic(default_fmt, specific_fmt,
                    title, url, author, created, modified,
                    optional_values=None):
    output_format = specific_fmt if specific_fmt is not None else default_fmt
    values = {
        'title': title,
        'url': url,
        'author': author,
        'created': created,
        'modified': modified,
    }
    if optional_values is not None:
      values.update(optional_values)
    print(DefaultFormatter().format(output_format, **values))


  def filter_issue(self, issue, should_filter_by_user=True):
    def maybe_filter_username(email):
      return not should_filter_by_user or username(email) == self.user
    if (maybe_filter_username(issue['author']) and
        self.filter_modified(issue['created'])):
      return True
    if (maybe_filter_username(issue['owner']) and
        (self.filter_modified(issue['created']) or
         self.filter_modified(issue['modified']))):
      return True
    for reply in issue['replies']:
      if self.filter_modified(reply['created']):
        if not should_filter_by_user:
          break
        if (username(reply['author']) == self.user
            or (self.user + '@') in reply['content']):
          break
    else:
      return False
    return True

  def filter_modified(self, modified):
    return self.modified_after < modified and modified < self.modified_before

  def auth_for_changes(self):
    #TODO(cjhopman): Move authentication check for getting changes here.
    pass

  def auth_for_reviews(self):
    # Reviews use all the same instances as changes so no authentication is
    # required.
    pass

  def get_changes(self):
    num_instances = len(gerrit_instances)
    with contextlib.closing(ThreadPool(num_instances)) as pool:
      gerrit_changes = pool.map_async(
          lambda instance: self.gerrit_search(instance, owner=self.user),
          gerrit_instances)
      gerrit_changes = itertools.chain.from_iterable(gerrit_changes.get())
      self.changes = list(gerrit_changes)

  def print_changes(self):
    if self.changes:
      self.print_heading('Changes')
      for change in self.changes:
        self.print_change(change)

  def print_access_errors(self):
    if self.access_errors:
      logging.error('Access Errors:')
      for error in self.access_errors:
        logging.error(error.rstrip())

  def get_reviews(self):
    num_instances = len(gerrit_instances)
    with contextlib.closing(ThreadPool(num_instances)) as pool:
      gerrit_reviews = pool.map_async(
          lambda instance: self.gerrit_search(instance, reviewer=self.user),
          gerrit_instances)
      gerrit_reviews = itertools.chain.from_iterable(gerrit_reviews.get())
      self.reviews = list(gerrit_reviews)

  def print_reviews(self):
    if self.reviews:
      self.print_heading('Reviews')
      for review in self.reviews:
        self.print_review(review)

  def get_issues(self):
    with contextlib.closing(ThreadPool(len(monorail_projects))) as pool:
      monorail_issues = pool.map(
          self.monorail_issue_search, monorail_projects.keys())
      monorail_issues = list(itertools.chain.from_iterable(monorail_issues))

    if not monorail_issues:
      return

    with contextlib.closing(ThreadPool(len(monorail_issues))) as pool:
      filtered_issues = pool.map(
          self.filter_modified_monorail_issue, monorail_issues)
      self.issues = [issue for issue in filtered_issues if issue]

  def get_referenced_issues(self):
    if not self.issues:
      self.get_issues()

    if not self.changes:
      self.get_changes()

    referenced_issue_uids = set(itertools.chain.from_iterable(
      change['bugs'] for change in self.changes))
    fetched_issue_uids = set(issue['uid'] for issue in self.issues)
    missing_issue_uids = referenced_issue_uids - fetched_issue_uids

    missing_issues_by_project = collections.defaultdict(list)
    for issue_uid in missing_issue_uids:
      project, issue_id = issue_uid.split(':')
      missing_issues_by_project[project].append(issue_id)

    for project, issue_ids in missing_issues_by_project.items():
      self.referenced_issues += self.monorail_get_issues(project, issue_ids)

  def print_issues(self):
    if self.issues:
      self.print_heading('Issues')
      for issue in self.issues:
        self.print_issue(issue)

  def print_changes_by_issue(self, skip_empty_own):
    if not self.issues or not self.changes:
      return

    self.print_heading('Changes by referenced issue(s)')
    issues = {issue['uid']: issue for issue in self.issues}
    ref_issues = {issue['uid']: issue for issue in self.referenced_issues}
    changes_by_issue_uid = collections.defaultdict(list)
    changes_by_ref_issue_uid = collections.defaultdict(list)
    changes_without_issue = []
    for change in self.changes:
      added = False
      for issue_uid in change['bugs']:
        if issue_uid in issues:
          changes_by_issue_uid[issue_uid].append(change)
          added = True
        if issue_uid in ref_issues:
          changes_by_ref_issue_uid[issue_uid].append(change)
          added = True
      if not added:
        changes_without_issue.append(change)

    # Changes referencing own issues.
    for issue_uid in issues:
      if changes_by_issue_uid[issue_uid] or not skip_empty_own:
        self.print_issue(issues[issue_uid])
      if changes_by_issue_uid[issue_uid]:
        print()
        for change in changes_by_issue_uid[issue_uid]:
          print('    ', end='')  # this prints no newline
          self.print_change(change)
        print()

    # Changes referencing others' issues.
    for issue_uid in ref_issues:
      assert changes_by_ref_issue_uid[issue_uid]
      self.print_issue(ref_issues[issue_uid])
      for change in changes_by_ref_issue_uid[issue_uid]:
        print('', end=' ')  # this prints one space due to comma, but no newline
        self.print_change(change)

    # Changes referencing no issues.
    if changes_without_issue:
      print(self.options.output_format_no_url.format(title='Other changes'))
      for change in changes_without_issue:
        print('', end=' ')  # this prints one space due to comma, but no newline
        self.print_change(change)

  def print_activity(self):
    self.print_changes()
    self.print_reviews()
    self.print_issues()

  def dump_json(self, ignore_keys=None):
    if ignore_keys is None:
      ignore_keys = ['replies']

    def format_for_json_dump(in_array):
      output = {}
      for item in in_array:
        url = item.get('url') or item.get('review_url')
        if not url:
          raise Exception('Dumped item %s does not specify url' % item)
        output[url] = dict(
            (k, v) for k,v in item.items() if k not in ignore_keys)
      return output

    class PythonObjectEncoder(json.JSONEncoder):
      def default(self, obj):  # pylint: disable=method-hidden
        if isinstance(obj, datetime):
          return obj.isoformat()
        if isinstance(obj, set):
          return list(obj)
        return json.JSONEncoder.default(self, obj)

    output = {
      'reviews': format_for_json_dump(self.reviews),
      'changes': format_for_json_dump(self.changes),
      'issues': format_for_json_dump(self.issues)
    }
    print(json.dumps(output, indent=2, cls=PythonObjectEncoder))


def main():
  parser = optparse.OptionParser(description=sys.modules[__name__].__doc__)
  parser.add_option(
      '-u', '--user', metavar='<email>',
      # Look for USER and USERNAME (Windows) environment variables.
      default=os.environ.get('USER', os.environ.get('USERNAME')),
      help='Filter on user, default=%default')
  parser.add_option(
      '-b', '--begin', metavar='<date>',
      help='Filter issues created after the date (mm/dd/yy)')
  parser.add_option(
      '-e', '--end', metavar='<date>',
      help='Filter issues created before the date (mm/dd/yy)')
  quarter_begin, quarter_end = get_quarter_of(datetime.today() -
                                              relativedelta(months=2))
  parser.add_option(
      '-Q', '--last_quarter', action='store_true',
      help='Use last quarter\'s dates, i.e. %s to %s' % (
        quarter_begin.strftime('%Y-%m-%d'), quarter_end.strftime('%Y-%m-%d')))
  parser.add_option(
      '-Y', '--this_year', action='store_true',
      help='Use this year\'s dates')
  parser.add_option(
      '-w', '--week_of', metavar='<date>',
      help='Show issues for week of the date (mm/dd/yy)')
  parser.add_option(
      '-W', '--last_week', action='count',
      help='Show last week\'s issues. Use more times for more weeks.')
  parser.add_option(
      '-a', '--auth',
      action='store_true',
      help='Ask to authenticate for instances with no auth cookie')
  parser.add_option(
      '-d', '--deltas',
      action='store_true',
      help='Fetch deltas for changes.')
  parser.add_option(
      '--no-referenced-issues',
      action='store_true',
      help='Do not fetch issues referenced by owned changes. Useful in '
           'combination with --changes-by-issue when you only want to list '
           'issues that have also been modified in the same time period.')
  parser.add_option(
      '--skip_servers',
      action='store',
      default='',
      help='A comma separated list of gerrit and rietveld servers to ignore')
  parser.add_option(
      '--skip-own-issues-without-changes',
      action='store_true',
      help='Skips listing own issues without changes when showing changes '
           'grouped by referenced issue(s). See --changes-by-issue for more '
           'details.')

  activity_types_group = optparse.OptionGroup(parser, 'Activity Types',
                               'By default, all activity will be looked up and '
                               'printed. If any of these are specified, only '
                               'those specified will be searched.')
  activity_types_group.add_option(
      '-c', '--changes',
      action='store_true',
      help='Show changes.')
  activity_types_group.add_option(
      '-i', '--issues',
      action='store_true',
      help='Show issues.')
  activity_types_group.add_option(
      '-r', '--reviews',
      action='store_true',
      help='Show reviews.')
  activity_types_group.add_option(
      '--changes-by-issue', action='store_true',
      help='Show changes grouped by referenced issue(s).')
  parser.add_option_group(activity_types_group)

  output_format_group = optparse.OptionGroup(parser, 'Output Format',
                              'By default, all activity will be printed in the '
                              'following format: {url} {title}. This can be '
                              'changed for either all activity types or '
                              'individually for each activity type. The format '
                              'is defined as documented for '
                              'string.format(...). The variables available for '
                              'all activity types are url, title, author, '
                              'created and modified. Format options for '
                              'specific activity types will override the '
                              'generic format.')
  output_format_group.add_option(
      '-f', '--output-format', metavar='<format>',
      default=u'{url} {title}',
      help='Specifies the format to use when printing all your activity.')
  output_format_group.add_option(
      '--output-format-changes', metavar='<format>',
      default=None,
      help='Specifies the format to use when printing changes. Supports the '
      'additional variable {reviewers}')
  output_format_group.add_option(
      '--output-format-issues', metavar='<format>',
      default=None,
      help='Specifies the format to use when printing issues. Supports the '
           'additional variable {owner}.')
  output_format_group.add_option(
      '--output-format-reviews', metavar='<format>',
      default=None,
      help='Specifies the format to use when printing reviews.')
  output_format_group.add_option(
      '--output-format-heading', metavar='<format>',
      default=u'{heading}:',
      help='Specifies the format to use when printing headings. '
           'Supports the variable {heading}.')
  output_format_group.add_option(
      '--output-format-no-url', default='{title}',
      help='Specifies the format to use when printing activity without url.')
  output_format_group.add_option(
      '-m', '--markdown', action='store_true',
      help='Use markdown-friendly output (overrides --output-format '
           'and --output-format-heading)')
  output_format_group.add_option(
      '-j', '--json', action='store_true',
      help='Output json data (overrides other format options)')
  parser.add_option_group(output_format_group)

  parser.add_option(
      '-v', '--verbose',
      action='store_const',
      dest='verbosity',
      default=logging.WARN,
      const=logging.INFO,
      help='Output extra informational messages.'
  )
  parser.add_option(
      '-q', '--quiet',
      action='store_const',
      dest='verbosity',
      const=logging.ERROR,
      help='Suppress non-error messages.'
  )
  parser.add_option(
      '-M', '--merged-only',
      action='store_true',
      dest='merged_only',
      default=False,
      help='Shows only changes that have been merged.')
  parser.add_option(
      '-C', '--completed-issues',
      action='store_true',
      dest='completed_issues',
      default=False,
      help='Shows only monorail issues that have completed (Fixed|Verified) '
           'by the user.')
  parser.add_option(
      '-o', '--output', metavar='<file>',
      help='Where to output the results. By default prints to stdout.')

  # Remove description formatting
  parser.format_description = (
      lambda _: parser.description)  # pylint: disable=no-member

  options, args = parser.parse_args()
  options.local_user = os.environ.get('USER')
  if args:
    parser.error('Args unsupported')
  if not options.user:
    parser.error('USER/USERNAME is not set, please use -u')
  # Retains the original -u option as the email address.
  options.email = options.user
  options.user = username(options.email)

  logging.basicConfig(level=options.verbosity)

  # python-keyring provides easy access to the system keyring.
  try:
    import keyring  # pylint: disable=unused-import,unused-variable,F0401
  except ImportError:
    logging.warning('Consider installing python-keyring')

  if not options.begin:
    if options.last_quarter:
      begin, end = quarter_begin, quarter_end
    elif options.this_year:
      begin, end = get_year_of(datetime.today())
    elif options.week_of:
      begin, end = (get_week_of(datetime.strptime(options.week_of, '%m/%d/%y')))
    elif options.last_week:
      begin, end = (get_week_of(datetime.today() -
                                timedelta(days=1 + 7 * options.last_week)))
    else:
      begin, end = (get_week_of(datetime.today() - timedelta(days=1)))
  else:
    begin = dateutil.parser.parse(options.begin)
    if options.end:
      end = dateutil.parser.parse(options.end)
    else:
      end = datetime.today()
  options.begin, options.end = begin, end
  if begin >= end:
    # The queries fail in peculiar ways when the begin date is in the future.
    # Give a descriptive error message instead.
    logging.error('Start date (%s) is the same or later than end date (%s)' %
                  (begin, end))
    return 1

  if options.markdown:
    options.output_format_heading = '### {heading}\n'
    options.output_format = '  * [{title}]({url})'
    options.output_format_no_url = '  * {title}'
  logging.info('Searching for activity by %s', options.user)
  logging.info('Using range %s to %s', options.begin, options.end)

  my_activity = MyActivity(options)
  my_activity.show_progress('Loading data')

  if not (options.changes or options.reviews or options.issues or
          options.changes_by_issue):
    options.changes = True
    options.issues = True
    options.reviews = True

  # First do any required authentication so none of the user interaction has to
  # wait for actual work.
  if options.changes or options.changes_by_issue:
    my_activity.auth_for_changes()
  if options.reviews:
    my_activity.auth_for_reviews()

  logging.info('Looking up activity.....')

  try:
    if options.changes or options.changes_by_issue:
      my_activity.get_changes()
    if options.reviews:
      my_activity.get_reviews()
    if options.issues or options.changes_by_issue:
      my_activity.get_issues()
    if not options.no_referenced_issues:
      my_activity.get_referenced_issues()
  except auth.LoginRequiredError as e:
    logging.error('auth.LoginRequiredError: %s', e)

  my_activity.show_progress('\n')

  my_activity.print_access_errors()

  output_file = None
  try:
    if options.output:
      output_file = open(options.output, 'w')
      logging.info('Printing output to "%s"', options.output)
      sys.stdout = output_file
  except (IOError, OSError) as e:
    logging.error('Unable to write output: %s', e)
  else:
    if options.json:
      my_activity.dump_json()
    else:
      if options.changes:
        my_activity.print_changes()
      if options.reviews:
        my_activity.print_reviews()
      if options.issues:
        my_activity.print_issues()
      if options.changes_by_issue:
        my_activity.print_changes_by_issue(
            options.skip_own_issues_without_changes)
  finally:
    if output_file:
      logging.info('Done printing to file.')
      sys.stdout = sys.__stdout__
      output_file.close()

  return 0


if __name__ == '__main__':
  # Fix encoding to support non-ascii issue titles.
  fix_encoding.fix_encoding()

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