# Copyright (c) 2011 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.
# pylint: disable-msg=C0111

"""Django chart models for performance key-build charts.

   Produce the data behind a google visualisation data table that can
   be rendered into a chart.

   Data entry points at this time include:
   -GetRangedKeyByBuildLinechartData(): produce a value by builds data table.
"""

from autotest_lib.frontend.afe import readonly_connection

import autotest_lib.frontend.croschart.chartmodels as chartmodels
import autotest_lib.frontend.croschart.chartutils as chartutils
from autotest_lib.frontend.croschart.charterrors import ChartDBError
from autotest_lib.frontend.croschart.charterrors import ChartInputError

try:
    import gviz_api
except ImportError:
    # Do nothing, in case this is part of a unit test.
    pass

# Can only get date order from the db.
DEFAULT_ORDER = 'ORDER BY test_started_time'

# Narrow data to a set of known machines.
HOSTNAME_QUERY_TEMPLATE = "AND hostname in ('%s')"


###############################################################################
# Models
def GetKeysByBuildLinechartData(test_name, test_keys, chrome_versions, query,
                                query_order=DEFAULT_ORDER):
  """Prepare and run the db query and massage the results."""

  def AggregateBuilds(test_keys, chrome_versions, data_list):
    """Groups and averages data by build and extracts job_tags."""
    # raw_dict
    #   build
    #     test_key: values
    raw_dict = {}  # unsummarized data
    builds_inorder = []  # summarized data
    job_tags = []

    # Aggregate all the data values by test_name, test_key, build.
    for build, tag, test_key, test_value in data_list:
      build = chartutils.AbbreviateBuild(build, chrome_versions)
      if not build:
        continue
      if not build in raw_dict:
        builds_inorder.append({'build': build})
        job_tags.append(tag)
      key_dict = raw_dict.setdefault(build, {})
      value_list = key_dict.setdefault(test_key, [])
      value_list.append(test_value)
    if not raw_dict:
      raise ChartDBError('No data returned')
    # Now calculate averages.
    for data_dict in builds_inorder:
      build_dict = raw_dict[data_dict['build']]
      for test_key, value_list in build_dict.iteritems():
        avg = round(sum(value_list, 0.0) / len(value_list), 2)
        data_dict[test_key] = avg
    return job_tags, builds_inorder

  def ToGVizJsonTable(test_keys, new_test_keys, table_data):
    """Massage data into gviz data table in proper order."""
    # Now format for gviz table.
    description = {'build': ('string', 'Build')}
    keys_in_order = ['build']
    for i in xrange(len(test_keys)):
      description[test_keys[i]] = ('number', new_test_keys[i])
      keys_in_order.append(test_keys[i])
    gviz_data_table = gviz_api.DataTable(description)
    gviz_data_table.LoadData(table_data)
    gviz_data_table = gviz_data_table.ToJSon(keys_in_order)
    return gviz_data_table

  cursor = readonly_connection.connection().cursor()
  cursor.execute('%s %s' % (query, query_order))
  job_tags, build_data = AggregateBuilds(test_keys, chrome_versions,
                                         cursor.fetchall())
  new_test_name, new_test_keys = chartutils.AbridgeCommonKeyPrefix(test_name,
                                                                   test_keys)
  gviz_data_table = ToGVizJsonTable(test_keys, new_test_keys, build_data)
  return {'test_name': test_name, 'test_keys': new_test_keys,
          'chart_title': new_test_name, 'gviz_data_table': gviz_data_table,
          'job_tags': job_tags}


def GetRangedKeyByBuildLinechartData(request):
  """Assemble the proper query and order."""
  ranged_queries = {'from_build': chartmodels.GetBuildRangedChartQuery,
                    'from_date': chartmodels.GetDateRangedChartQuery,
                    'interval': chartmodels.GetIntervalRangedChartQuery}
  query_list = [chartmodels.GetBasePerfQuery(request)]
  for range_key in ['from_build', 'from_date', 'interval', None]:
    if request.GET.get(range_key, None):
      break
  if not range_key:
    raise ChartInputError('One interval-type parameter must be supplied.')
  query_list.append(ranged_queries[range_key](request))
  chrome_versions = chartutils.GetChromeVersions(request)
  host_names = request.GET.get('hostnames')
  if host_names:
    query_list.append(HOSTNAME_QUERY_TEMPLATE %
                      "','".join(host_names.split(',')))
  test_name, test_keys = chartutils.GetTestNameKeys(request.GET.get('testkey'))
  data_dict = GetKeysByBuildLinechartData(test_name, test_keys, chrome_versions,
                                          ' '.join(query_list))
  return data_dict
