#!/usr/bin/env python
#  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
#
#  Use of this source code is governed by a BSD-style license
#  that can be found in the LICENSE file in the root of the source
#  tree. An additional intellectual property rights grant can be found
#  in the file PATENTS.  All contributing project authors may
#  be found in the AUTHORS file in the root of the source tree.

import os
import gviz_api
import webrtc.data_helper

def main():
  """
  This Python script displays a web page with test created with the
  video_quality_measurement program, which is a tool in WebRTC.

  The script requires on two external files and one Python library:
  - A HTML template file with layout and references to the json variables
    defined in this script
  - A data file in Python format, containing the following:
    - test_configuration - a dictionary of test configuration names and values.
    - frame_data_types - a dictionary that maps the different metrics to their
      data types.
    - frame_data - a list of dictionaries where each dictionary maps a metric to
      it's value.
  - The gviz_api.py of the Google Visualization Python API, available at
    http://code.google.com/p/google-visualization-python/

  The HTML file is shipped with the script, while the data file must be
  generated by running video_quality_measurement with the --python flag
  specified.
  """
  print 'Content-type: text/html\n' # the newline is required!

  page_template_filename = '../templates/chart_page_template.html'
  # The data files must be located in the project tree for app engine being
  # able to access them.
  data_filenames = ['../data/vp8_sw.py', '../data/vp8_hw.py']
  # Will contain info/error messages to be displayed on the resulting page.
  messages = []
  # Load the page HTML template.
  try:
    f = open(page_template_filename)
    page_template = f.read()
    f.close()
  except IOError as e:
    ShowErrorPage('Cannot open page template file: %s<br>Details: %s' %
                  (page_template_filename, e))
    return

  # Read data from external Python script files. First check that they exist.
  for filename in data_filenames:
    if not os.path.exists(filename):
      messages.append('Cannot open data file: %s' % filename)
      data_filenames.remove(filename)

  # Read data from all existing input files.
  data_list = []
  test_configurations = []
  names = []

  for filename in data_filenames:
    read_vars = {} # empty dictionary to load the data into.
    execfile(filename, read_vars, read_vars)

    test_configuration = read_vars['test_configuration']
    table_description = read_vars['frame_data_types']
    table_data = read_vars['frame_data']

    # Verify the data in the file loaded properly.
    if not table_description or not table_data:
      messages.append('Invalid input file: %s. Missing description list or '
                      'data dictionary variables.' % filename)
      continue

    # Frame numbers appear as number type in the data, but Chart API requires
    # values of the X-axis to be of string type.
    # Change the frame_number column data type:
    table_description['frame_number'] = ('string', 'Frame number')
    # Convert all the values to string types:
    for row in table_data:
      row['frame_number'] = str(row['frame_number'])

    # Store the unique data from this file in the high level lists.
    test_configurations.append(test_configuration)
    data_list.append(table_data)
    # Name of the test run must be present.
    test_name = FindConfiguration(test_configuration, 'name')
    if not test_name:
      messages.append('Invalid input file: %s. Missing configuration key '
                      '"name"', filename)
      continue
    names.append(test_name)

  # Create data helper and build data tables for each graph.
  helper = webrtc.data_helper.DataHelper(data_list, table_description,
                                         names, messages)

  # Loading it into gviz_api.DataTable objects and create JSON strings.
  description, data = helper.CreateConfigurationTable(test_configurations)
  configurations = gviz_api.DataTable(description, data)
  json_configurations = configurations.ToJSon()  # pylint: disable=W0612

  description, data = helper.CreateData('ssim')
  ssim = gviz_api.DataTable(description, data)
  # pylint: disable=W0612
  json_ssim_data = ssim.ToJSon(helper.GetOrdering(description))

  description, data = helper.CreateData('psnr')
  psnr = gviz_api.DataTable(description, data)
  # pylint: disable=W0612
  json_psnr_data = psnr.ToJSon(helper.GetOrdering(description))

  description, data = helper.CreateData('packets_dropped')
  packet_loss = gviz_api.DataTable(description, data)
  # pylint: disable=W0612
  json_packet_loss_data = packet_loss.ToJSon(helper.GetOrdering(description))

  description, data = helper.CreateData('bit_rate')
  # Add a column of data points for the desired bit rate to be plotted.
  # (uses test configuration from the last data set, assuming it is the same
  # for all of them)
  desired_bit_rate = FindConfiguration(test_configuration, 'bit_rate_in_kbps')
  if not desired_bit_rate:
    ShowErrorPage('Cannot configuration field named "bit_rate_in_kbps"')
    return
  desired_bit_rate = int(desired_bit_rate)
  # Add new column data type description.
  description['desired_bit_rate'] = ('number', 'Desired bit rate (kbps)')
  for row in data:
    row['desired_bit_rate'] = desired_bit_rate
  bit_rate = gviz_api.DataTable(description, data)
  # pylint: disable=W0612
  json_bit_rate_data = bit_rate.ToJSon(helper.GetOrdering(description))

  # Format the messages list with newlines.
  messages = '\n'.join(messages)

  # Put the variables as JSon strings into the template.
  print page_template % vars()

def FindConfiguration(configuration, name):
  """ Finds a configuration value using it's name.
      Returns the first configuration with a matching name. Returns None if no
      matching configuration is found. """
  return_value = None
  for row in configuration:
    if row['name'] == name:
      return_value = row['value']
      break
  return return_value

def ShowErrorPage(error_message):
  print '<html><body>%s</body></html>' % error_message

if __name__ == '__main__':
  main()
