# Copyright (c) 2012 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.

"""cros stats: Generate stats reports from CIDB."""

from __future__ import print_function

import datetime
import sys

from chromite.cbuildbot import constants
from chromite.lib import build_time_stats
from chromite.cli import command
from chromite.lib import commandline
from chromite.cli.cros import cros_cidbcreds  # TODO: Move into lib???
from chromite.lib import cros_logging as logging

# Used by --build-type option.
BUILD_TYPE_MAP = {
    'cq': constants.CQ_MASTER,
    'canary': constants.CANARY_MASTER,
    'chrome-pfq': constants.PFQ_MASTER,
}


@command.CommandDecorator('stats')
class StatsCommand(command.CliCommand):
  """Script that shows build timing for a build, and it's stages."""

  def __init__(self, options):
    super(StatsCommand, self).__init__(options)

  @classmethod
  def AddParser(cls, parser):
    super(cls, StatsCommand).AddParser(parser)

    stats_args = parser.add_argument_group()

    stats_args.add_argument('--cred-dir', type='path',
                            metavar='CIDB_CREDENTIALS_DIR',
                            help='Database credentials directory with'
                                 ' certificates and other connection'
                                 ' information. Obtain your credentials'
                                 ' at go/cros-cidb-admin .')

    stats_args.add_argument('--end-date', action='store', type='date',
                            default=None,
                            help='Limit scope to an end date in the past.')

    stats_args.add_argument('--csv', action='store_true', default=False,
                            help='Output in CSV format.')

    stats_args.add_argument('--stages', action='store_true', default=True,
                            help='Do not show stats for all stages run.')
    stats_args.add_argument('--nostages', dest='stages', action='store_false',
                            help='Do not show stats for all stages run.')

    # Which builds are we generating a report for?
    ex_group = parser.add_mutually_exclusive_group(required=True)

    # Ask for pull out a single build id to compare against other values.
    ex_group.add_argument('--build-id', action='store', type=int, default=None,
                          help="Single build with comparison to 'normal'.")

    # Look at all builds for a build_config.
    ex_group.add_argument('--build-config', action='store', default=None,
                          help='Build config to gather stats for.')

    # Look at all builds for a master/slave group.
    ex_group.add_argument('--build-type', default=None,
                          choices=BUILD_TYPE_MAP.keys(),
                          help='Build master/salves to gather stats for: cq.')

    # How many builds are included, for builder/build-types.
    start_group = parser.add_mutually_exclusive_group()
    start_group.add_argument('--start-date', action='store', type='date',
                             default=None,
                             help='Limit scope to a start date in the past.')
    start_group.add_argument('--month', action='store_true', default=False,
                             help='Limit scope to the past 30 days up to now.')
    start_group.add_argument('--week', action='store_true', default=False,
                             help='Limit scope to the past week up to now.')
    start_group.add_argument('--day', action='store_true', default=False,
                             help='Limit scope to the past day up to now.')
    start_group.add_argument('--trending', action='store_true', default=False,
                             help='Show stats for all builds by month.')

    # What kind of report do we generate?
    report_group = parser.add_mutually_exclusive_group()
    report_group.add_argument('--report', default='standard',
                              choices=['standard', 'stability', 'success'],
                              help='What type of report to generate?')


  @staticmethod
  def OptionsToStartEndDates(options):
    end_date = options.end_date or datetime.datetime.now().date()

    if options.month:
      start_date = end_date - datetime.timedelta(days=30)
    elif options.day:
      start_date = end_date - datetime.timedelta(days=1)
    elif options.start_date:
      start_date = options.start_date
    elif options.trending:
      start_date, end_date = None, None
    else:
      # Default of past_week.
      start_date = end_date - datetime.timedelta(days=7)

    return start_date, end_date


  def Run(self):
    """Run cros build."""
    self.options.Freeze()

    commandline.RunInsideChroot(self)

    credentials = self.options.cred_dir
    if not credentials:
      credentials = cros_cidbcreds.CheckAndGetCIDBCreds()

    # Delay import so sqlalchemy isn't pulled in until we need it.
    from chromite.lib import cidb

    db = cidb.CIDBConnection(credentials)

    # Timeframe for discovering builds, if options.build_id not used.
    start_date, end_date = self.OptionsToStartEndDates(self.options)

    # Trending is sufficiently different to be handled on it's own.
    if not self.options.trending and self.options.report != 'success':
      assert not self.options.csv, (
          '--csv can only be used with --trending or --report success.')

    # Data about a single build (optional).
    focus_build = None

    if self.options.build_id:
      logging.info('Gathering data for %s', self.options.build_id)
      focus_status = build_time_stats.BuildIdToBuildStatus(
          db, self.options.build_id)
      focus_build = build_time_stats.GetBuildTimings(focus_status)

      build_config = focus_status['build_config']
      builds_statuses = build_time_stats.BuildConfigToStatuses(
          db, build_config, start_date, end_date)
      description = 'Focus %d - %s' % (self.options.build_id, build_config)

    elif self.options.build_config:
      builds_statuses = build_time_stats.BuildConfigToStatuses(
          db, self.options.build_config, start_date, end_date)
      description = 'Config %s' % self.options.build_config

    elif self.options.build_type:
      builds_statuses = build_time_stats.MasterConfigToStatuses(
          db, BUILD_TYPE_MAP[self.options.build_type], start_date, end_date)
      description = 'Type %s' % self.options.build_type

    if not builds_statuses:
      logging.critical('No Builds Found For: %s', description)
      return 1

    if self.options.report == 'success':
      # Calculate per-build success rates and per-stage success rates.
      build_success_rates = build_time_stats.GetBuildSuccessRates(
          builds_statuses)
      stage_success_rates = (
          build_time_stats.GetStageSuccessRates(builds_statuses) if
          self.options.stages else {})
      if self.options.csv:
        build_time_stats.SuccessReportCsv(
            sys.stdout, build_success_rates, stage_success_rates)
      else:
        build_time_stats.SuccessReport(
            sys.stdout, description, build_success_rates, stage_success_rates)
      return 0

    # Compute per-build timing.
    builds_timings = [build_time_stats.GetBuildTimings(status)
                      for status in builds_statuses]

    if not builds_timings:
      logging.critical('No timing results For: %s', description)
      return 1

    # Report results.
    if self.options.report == 'standard':
      build_time_stats.Report(
          sys.stdout,
          description,
          focus_build,
          builds_timings,
          self.options.stages,
          self.options.trending,
          self.options.csv)
    elif self.options.report == 'stability':
      build_time_stats.StabilityReport(
          sys.stdout,
          description,
          builds_timings)
