# 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.

"""Generate detail table .html files for board-netbook-testcategories."""

import datetime
import logging
import os

from django.shortcuts import render_to_response

import dash_util

from build_info import BuildInfo
from dash_view import SummaryRanges
from table_builder import TableBuilder

# String resources.
from dash_strings import BVT_TAG
from dash_strings import DASHBOARD_MAIN
from dash_strings import EMAILS_SUMMARY_FILE
from dash_strings import KERNEL_TABLE_FILE
from dash_strings import KERNEL_WATERFALL_FILE
from dash_strings import KERNELTEST_TAG
from dash_strings import PERF_BUILDS_FILE
from dash_strings import TEST_DETAILS_FILE
from dash_strings import TEST_LANDING_FILE
from dash_strings import TEST_WATERFALL_FILE
from dash_strings import UNKNOWN_TIME_STR


def _BuildNetbookHTML(
    dash_base_dir, dash_view, tpl_netbook, tpl_board,
    default_category, dash_options):
  """Create table files for all categories of a netbook-board.

  Produces a set of pages of test results for a given netbook,
  board and categories with tests executed.

  Args:
    dash_base_dir: base of dashboard output files.
    dash_view: data model with all test result details.
    tpl_netbook: netbook (e.g. netbook_MARIO_MP) for these pages.
    tpl_board: board (e.g. x86-mario) for these pages.
    default_category: landing page when switching pages.
    dash_options: config options used for setting landing pages.
  """
  base_dir = os.path.join(dash_base_dir, tpl_netbook, tpl_board)
  if not os.path.exists(base_dir):
    dash_util.MakeChmodDirs(base_dir)
  logging.info('build %s into %s', tpl_netbook, base_dir)

  # Build a details page for each category.
  alternate_landings = dash_options.get('alternatelandings', {})
  tpl_board_netbooks = [
      (n, alternate_landings.get(tpl_board, {}).get(n, BVT_TAG))
      for n in dash_view.GetNetbooksWithBoardType(tpl_board)
      if n != tpl_netbook]
  tpl_other_boards = sorted(
      [b
       for b in dash_view.GetNetbookBoardTypes(tpl_netbook)
       if b != tpl_board])
  tpl_last_updated = dash_view.GetFormattedLastUpdated()

  tpl_categories = dash_view.GetUICategories(tpl_netbook, tpl_board)
  if not default_category in tpl_categories:
    tpl_categories.append(default_category)
  tpl_categories.sort()

  tpl_categories_with_color = []
  for tpl_category in tpl_categories:
    table_builder = TableBuilder(dash_base_dir, tpl_netbook, tpl_board,
                                 tpl_category)
    total, failed = table_builder.CountTestList()
    if failed:
      label = tpl_category + '(%d/%d)' % (total, failed)
    else:
      label = tpl_category + '(%d)' % total
    if total == 0:
      bg_class = 'white'
    elif failed == 0:
      bg_class = 'success'
    elif total == failed:
      bg_class = 'failure'
    else:
      bg_class = 'warning'
    tpl_categories_with_color.append(
        (tpl_category, table_builder, label, bg_class))

  # Produce a test results page for each test category.
  tpl_perf_builds = None
  for tpl_category, table_builder, label, bg_class in tpl_categories_with_color:
    tpl_tables = table_builder.BuildTables()
    if tpl_category == BVT_TAG and tpl_tables:
      tpl_perf_builds = tpl_tables[0]['body']
    dash_util.SaveHTML(
        os.path.join(base_dir, '%s.html' % tpl_category),
        render_to_response(
            os.path.join('tables/details', TEST_DETAILS_FILE),
            locals()).content)

  # Produce a performance landing page.
  tpl_perf_available = False
  if 'alerts' in dash_options:
    for alert in dash_options['alerts']:
      if ('platforms' in alert and
          {tpl_board: tpl_netbook} in alert['platforms']):
        tpl_perf_available = True
  dash_util.SaveHTML(
      os.path.join(base_dir, PERF_BUILDS_FILE),
      render_to_response(
          os.path.join('tables/details', PERF_BUILDS_FILE),
          locals()).content)


def _GetLandingDetails(dash_view, summary_ranges, netbook, board, category,
                       build):
  """Gather the summary details for one build (row).

  If the dashboard presented results from one source this
  would not be needed.  Since we grab data from test results,
  test attributes and crash summaries this sort of function
  is needed to collect distributed data for one build and category.

  Args:
    dash_view: data model with all test result details.
    summary_ranges: limits for data queries in this summary.
    netbook: netbook (e.g. netbook_MARIO_MP) for these pages.
    board: board (e.g. x86-mario) for these pages.
    category: summary producted for bvt now, maybe something else later.
    build: build to use.

  Returns:
    Tuple of data for populating one waterfall row (build).
  """
  job_attempted, job_good, passed, total = dash_view.GetCategorySummary(
      netbook, board, category, build)
  kernel = summary_ranges.GetKernel(board, netbook, build)
  failed_tests = dash_view.GetCategoryFailedTests(
      netbook, board, category, build)
  if category == BVT_TAG:
    category = None
  crashes, crash_count, crash_category = (
      dash_view.GetCrashes().GetBuildCrashSummary(netbook, board, build,
                                                  category))
  # x86-alex-r18 -> x86-alex
  # x86-generic-full -> x86-generic-full
  release_index = board.rfind('-r')
  if release_index > 0:
    pure_board = board[:release_index]
  else:
    pure_board = board
  return (board, pure_board, netbook, build, job_attempted, job_good, passed,
          total, kernel, failed_tests, crashes, crash_count, crash_category)


def BuildLandingSummaries(dash_view, category, tots, branches, summary_ranges):
  """Produces individual table for each board of test summaries per build.

  This produces the data for the 'new-style' (waterfall) dashboard summary.

  Args:
    dash_view: data model with all test result details.
    category: summary producted for bvt now, maybe something else later.
    tots: boards to be grouped at the top of page.
    branches: boards to be grouped next.
    summary_ranges: limits for data queries in this summary.

  Returns:
    A dictionary with the data for the waterfall display.
  """
  platforms = []
  builds = {}
  build_info = BuildInfo()
  results_dict = {}
  releases = set()
  irregular_releases = set()

  for board in tots + branches:
    parsed_board, release = dash_view.ParseBoard(board)
    if release:
      releases.add(release)
    else:
      irregular_releases.add(board)
    for build_number in summary_ranges.GetBuildNumbers(board):
      build_results = results_dict.setdefault(build_number, {})
      for netbook in summary_ranges.GetNetbooks(board):
        # Aggregate the test summaries for each platform.
        platform = (parsed_board, netbook)
        if not platform in platforms:
          platforms.append(platform)
        if build_results.get(platform):
          logging.info('Multiple results for %s, %s', build_number, platform)
          continue
        build_results[platform] = _GetLandingDetails(
            dash_view, summary_ranges, netbook, board, category, build_number)
        # Keep track of earliest test job start time for each build.
        time_key = (netbook, board, category, build_number)
        start_time, _, _ = dash_view.GetJobTimesNone(*time_key)
        if not start_time:
          continue
        early_start = builds.setdefault(build_number, (start_time, time_key))
        if start_time < early_start[0]:
          builds[build_number] = (start_time, time_key)

  # Include the earliest job date among the platforms to be shown as the
  # overall 'release' (r15) test start date-time.
  organized_results = []
  for build, (start_time, time_key) in sorted(builds.iteritems(), reverse=True,
                                              key=lambda (k, v): v[0]):
    build_results = []
    for platform in platforms:
      build_results.append(results_dict.get(build, {}).get(platform))
    if time_key:
      formatted_start, _, _ = dash_view.GetFormattedJobTimes(*time_key)
    else:
      formatted_start = None
    if build[0].lower() == 'r':
      # R16-w.x.y format build number.
      build_release = build.split('-')[0][1:]
    else:
      # 0.15.x.y format build number.
      build_release = build.split('.')[1]
    organized_results.append((build, build_release,
                              formatted_start, build_results))

  return {'platforms': platforms,
          'irregular': irregular_releases,
          'releases': sorted(releases, reverse=True),
          'results': organized_results}


def BuildSummaryHTML(base_dir, html_filename, tpl_summary_data, last_updated):
  """Render actual page and save to an html file.

  Args:
    base_dir: base where resulting html file goes.
    html_filename: actual filename differs in views.
    tpl_summary_data: this data consumed by the template.
    last_updated: published on output pages.

  Render Variables:
    last_updated: date used by the template.
  """
  full_filepath = os.path.join(base_dir, html_filename)
  tpl_last_updated = last_updated

  dash_util.SaveHTML(
      full_filepath,
      render_to_response(
          os.path.join('tables/summary', html_filename), locals()).content)


def BuildAllTables(dash_base_dir, dash_view, dash_options, summary_limit,
                   waterfall_limit):
  """Build all detail pages and a few summary pages as well.

  Builds the detail pages for each netbook/board/category and then a
  waterfall-style summary and a few other summary pages.

  Args:
    dash_base_dir: base of dashboard output files.
    dash_view: data model with all test result details.
    dash_options: config options used for setting landing pages.
    summary_limit: only show n rows/table on the summary page.
    waterfall_limit: only show n rows on the waterfall summary page.

  Render Variables:
    last_updated: date used by the template.
  """
  tpl_last_updated = dash_view.GetFormattedLastUpdated()
  netbooks = dash_options.get('debug_netbook', dash_view.netbooks)
  for netbook in netbooks:
    for board_type in dash_view.GetNetbookBoardTypes(netbook):
      _BuildNetbookHTML(dash_base_dir, dash_view, netbook, board_type,
                        BVT_TAG, dash_options)

  for summary_file, build_fn, category, limit in (
      (TEST_WATERFALL_FILE, BuildLandingSummaries, BVT_TAG, waterfall_limit),
      (KERNEL_WATERFALL_FILE, BuildLandingSummaries, KERNELTEST_TAG,
       waterfall_limit)):

    summary_ranges = SummaryRanges(dash_view, category, limit)
    boards = summary_ranges.GetBoards()
    tots = []
    branches = []
    nonpriority = []
    for board in boards:
      if board in dash_options['priorityboards_tot']:
        tots.append(board)
      elif board in dash_options['priorityboards']:
        branches.append(board)
      else:
        nonpriority.append(board)
    branches += nonpriority

    BuildSummaryHTML(
        dash_base_dir,
        summary_file,
        build_fn(dash_view, category, tots, branches, summary_ranges),
        tpl_last_updated)

  dash_util.SaveHTML(
      os.path.join(dash_base_dir, TEST_LANDING_FILE),
      render_to_response(
          os.path.join('tables/summary', TEST_LANDING_FILE),
          locals()).content)
  dash_util.SaveHTML(
      os.path.join(dash_base_dir, EMAILS_SUMMARY_FILE),
      render_to_response(
          os.path.join('tables/summary', EMAILS_SUMMARY_FILE),
          locals()).content)


if __name__ == '__main__':
  print 'Run %s with --table-generate.' % DASHBOARD_MAIN
