#!/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()

  description, data = helper.CreateData('ssim')
  ssim = gviz_api.DataTable(description, data)
  json_ssim_data = ssim.ToJSon(helper.GetOrdering(description))

  description, data = helper.CreateData('psnr')
  psnr = gviz_api.DataTable(description, data)
  json_psnr_data = psnr.ToJSon(helper.GetOrdering(description))

  description, data = helper.CreateData('packets_dropped')
  packet_loss = gviz_api.DataTable(description, data)
  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)
  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()
