#!/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'
  _SUITE_ATTR = 'suite'
  _DESCRIPTION_ATTR = 'description'
  _EXTRA_BUILD_ARGS_ATTR = 'extra_build_args'
  _FULL_MAKE_ATTR = 'full_make'
  _GRANTED_PERMISSIONS_ATTR = 'granted_permissions'

  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.SetIsGrantedPermissions(self._ParseAttribute(suite_element,
                                                  self._GRANTED_PERMISSIONS_ATTR,
                                                  False, default_value=True))
    test_suite.SetSuite(self._ParseAttribute(suite_element, self._SUITE_ATTR, False,
                                           default_value=None))
    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=''))
    test_suite.SetIsFullMake(self._ParseAttribute(
        suite_element, self._FULL_MAKE_ATTR, False, default_value=False))


  def _ParseAttribute(self, suite_element, attribute_name, mandatory,
                      default_value=None):
    if suite_element.hasAttribute(attribute_name):
      value = suite_element.getAttribute(attribute_name)
      if default_value in (True, False):
        value = value.lower() == "true"
    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
