#!/usr/bin/python2.4
#
#
# Copyright 2009, The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Utility to parse suite info from xml."""

# Python imports
import xml.dom.minidom
import xml.parsers

# local imports
import errors
import logger
import host_test
import instrumentation_test
import native_test


class XmlSuiteParser(object):
  """Parses XML attributes common to all TestSuite's."""

  # common attributes
  _NAME_ATTR = 'name'
  _BUILD_ATTR = 'build_path'
  _CONTINUOUS_ATTR = 'continuous'
  _CTS_ATTR = 'cts'
  _DESCRIPTION_ATTR = 'description'
  _EXTRA_BUILD_ARGS_ATTR = 'extra_build_args'

  def Parse(self, element):
    """Populates common suite attributes from given suite xml element.

    Args:
      element: xml node to parse
    Raises:
      ParseError if a required attribute is missing.
    Returns:
      parsed test suite or None
    """
    parser = None
    if element.nodeName == InstrumentationParser.TAG_NAME:
      parser = InstrumentationParser()
    elif element.nodeName == NativeParser.TAG_NAME:
      parser = NativeParser()
    elif element.nodeName == HostParser.TAG_NAME:
      parser = HostParser()
    else:
      logger.Log('Unrecognized tag %s found' % element.nodeName)
      return None
    test_suite = parser.Parse(element)
    return test_suite

  def _ParseCommonAttributes(self, suite_element, test_suite):
    test_suite.SetName(self._ParseAttribute(suite_element, self._NAME_ATTR,
                                            True))
    test_suite.SetBuildPath(self._ParseAttribute(suite_element,
                                                 self._BUILD_ATTR, True))
    test_suite.SetContinuous(self._ParseAttribute(suite_element,
                                                  self._CONTINUOUS_ATTR,
                                                  False, default_value=False))
    test_suite.SetCts(self._ParseAttribute(suite_element, self._CTS_ATTR, False,
                                           default_value=False))
    test_suite.SetDescription(self._ParseAttribute(suite_element,
                                                   self._DESCRIPTION_ATTR,
                                                   False,
                                                   default_value=''))
    test_suite.SetExtraBuildArgs(self._ParseAttribute(
        suite_element, self._EXTRA_BUILD_ARGS_ATTR, False, default_value=''))

  def _ParseAttribute(self, suite_element, attribute_name, mandatory,
                      default_value=None):
    if suite_element.hasAttribute(attribute_name):
      value = suite_element.getAttribute(attribute_name)
    elif mandatory:
      error_msg = ('Could not find attribute %s in %s' %
                   (attribute_name, self.TAG_NAME))
      raise errors.ParseError(msg=error_msg)
    else:
      value = default_value
    return value


class InstrumentationParser(XmlSuiteParser):
  """Parses instrumentation suite attributes from xml."""

  # for legacy reasons, the xml tag name for java (device) tests is 'test'
  TAG_NAME = 'test'

  _PKG_ATTR = 'package'
  _RUNNER_ATTR = 'runner'
  _CLASS_ATTR = 'class'
  _TARGET_ATTR = 'coverage_target'

  def Parse(self, suite_element):
    """Creates suite and populate with data from xml element."""
    suite = instrumentation_test.InstrumentationTestSuite()
    XmlSuiteParser._ParseCommonAttributes(self, suite_element, suite)
    suite.SetPackageName(self._ParseAttribute(suite_element, self._PKG_ATTR,
                                              True))
    suite.SetRunnerName(self._ParseAttribute(
        suite_element, self._RUNNER_ATTR, False,
        instrumentation_test.InstrumentationTestSuite.DEFAULT_RUNNER))
    suite.SetClassName(self._ParseAttribute(suite_element, self._CLASS_ATTR,
                                            False))
    suite.SetTargetName(self._ParseAttribute(suite_element, self._TARGET_ATTR,
                                             False))
    return suite


class NativeParser(XmlSuiteParser):
  """Parses native suite attributes from xml."""

  TAG_NAME = 'test-native'

  def Parse(self, suite_element):
    """Creates suite and populate with data from xml element."""
    suite = native_test.NativeTestSuite()
    XmlSuiteParser._ParseCommonAttributes(self, suite_element, suite)
    return suite


class HostParser(XmlSuiteParser):
  """Parses host suite attributes from xml."""

  TAG_NAME = 'test-host'

  _CLASS_ATTR = 'class'
  # TODO: consider obsoleting in favor of parsing the Android.mk to find the
  # jar name
  _JAR_ATTR = 'jar_name'

  def Parse(self, suite_element):
    """Creates suite and populate with data from xml element."""
    suite = host_test.HostTestSuite()
    XmlSuiteParser._ParseCommonAttributes(self, suite_element, suite)
    suite.SetClassName(self._ParseAttribute(suite_element, self._CLASS_ATTR,
                                            True))
    suite.SetJarName(self._ParseAttribute(suite_element, self._JAR_ATTR, True))
    return suite
