# Copyright 2015, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""Generate XML and HTML test reports."""

from __future__ import print_function

try:
  from mako.runtime import Context
  from mako.template import Template
  from mako import exceptions
except (ImportError):
  pass  # Mako not installed but it is ok. 
import os
import string
import xml.etree.cElementTree as ET


def _filter_msg(msg, output_format):
  """Filters out nonprintable and illegal characters from the message."""
  if output_format in ['XML', 'HTML']:
    # keep whitespaces but remove formfeed and vertical tab characters
    # that make XML report unparseable.
    filtered_msg = filter(
        lambda x: x in string.printable and x != '\f' and x != '\v',
        msg.decode('UTF-8', 'ignore'))
    if output_format == 'HTML':
      filtered_msg = filtered_msg.replace('"', '&quot;')
    return filtered_msg
  else:
    return msg


def render_junit_xml_report(resultset, xml_report):
  """Generate JUnit-like XML report."""
  root = ET.Element('testsuites')
  testsuite = ET.SubElement(root, 'testsuite', id='1', package='grpc', 
                            name='tests')
  for shortname, results in resultset.items():
    for result in results:
      xml_test = ET.SubElement(testsuite, 'testcase', name=shortname) 
      if result.elapsed_time:
        xml_test.set('time', str(result.elapsed_time))
      ET.SubElement(xml_test, 'system-out').text = _filter_msg(result.message,
                                                               'XML')
      if result.state == 'FAILED':
        ET.SubElement(xml_test, 'failure', message='Failure')
      elif result.state == 'TIMEOUT':
        ET.SubElement(xml_test, 'error', message='Timeout')
  tree = ET.ElementTree(root)
  tree.write(xml_report, encoding='UTF-8')


def render_interop_html_report(
  client_langs, server_langs, test_cases, auth_test_cases, http2_cases, 
  resultset, num_failures, cloud_to_prod, prod_servers, http2_interop):
  """Generate HTML report for interop tests."""
  template_file = 'tools/run_tests/interop_html_report.template'
  try:
    mytemplate = Template(filename=template_file, format_exceptions=True)
  except NameError:
    print('Mako template is not installed. Skipping HTML report generation.')
    return
  except IOError as e:
    print('Failed to find the template %s: %s' % (template_file, e))
    return

  sorted_test_cases = sorted(test_cases)
  sorted_auth_test_cases = sorted(auth_test_cases)
  sorted_http2_cases = sorted(http2_cases)
  sorted_client_langs = sorted(client_langs)
  sorted_server_langs = sorted(server_langs)
  sorted_prod_servers = sorted(prod_servers)

  args = {'client_langs': sorted_client_langs, 
          'server_langs': sorted_server_langs,
          'test_cases': sorted_test_cases,
          'auth_test_cases': sorted_auth_test_cases,
          'http2_cases': sorted_http2_cases,
          'resultset': resultset,
          'num_failures': num_failures,
          'cloud_to_prod': cloud_to_prod,
          'prod_servers': sorted_prod_servers,
          'http2_interop': http2_interop}

  html_report_out_dir = 'reports' 
  if not os.path.exists(html_report_out_dir):
    os.mkdir(html_report_out_dir) 
  html_file_path = os.path.join(html_report_out_dir, 'index.html')
  try:
    with open(html_file_path, 'w') as output_file:
      mytemplate.render_context(Context(output_file, **args))
  except:
    print(exceptions.text_error_template().render())
    raise

