#!/usr/bin/python2.4
#
#
# Copyright 2008, 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.
import xml.dom.minidom
import xml.parsers
import os


import coverage_target
import logger
import errors

class CoverageTargets:
  """Accessor for the code coverage target xml file
  Expects the following format:
  <targets>
    <target
      name=""
      type="JAVA_LIBRARIES|APPS"
      build_path=""

      [<src path=""/>] (0..*)  - These are relative to build_path. If missing,
                                 assumes 'src'
    >/target>

    TODO: add more format checking
  """

  _TARGET_TAG_NAME = 'coverage_target'
  _NAME_ATTR = 'name'
  _TYPE_ATTR = 'type'
  _BUILD_ATTR = 'build_path'
  _SRC_TAG = 'src'
  _PATH_ATTR = 'path'

  def __init__(self, ):
    self._target_map= {}

  def __iter__(self):
    return iter(self._target_map.values())

  def Parse(self, file_path):
    """Parse the coverage target data from from given file path, and add it to
       the current object
       Args:
         file_path: absolute file path to parse
       Raises:
         errors.ParseError if file_path cannot be parsed
    """
    try:
      doc = xml.dom.minidom.parse(file_path)
    except IOError:
      # Error: The results file does not exist
      logger.Log('Results file %s does not exist' % file_path)
      raise errors.ParseError
    except xml.parsers.expat.ExpatError:
      logger.Log('Error Parsing xml file: %s ' %  file_path)
      raise errors.ParseError

    target_elements = doc.getElementsByTagName(self._TARGET_TAG_NAME)

    for target_element in target_elements:
      target = coverage_target.CoverageTarget()
      self._ParseCoverageTarget(target, target_element)
      self._AddTarget(target)

  def _AddTarget(self, target):
    self._target_map[target.GetName()] = target

  def GetBuildTargets(self):
    """ returns list of target names """
    build_targets = []
    for target in self:
      build_targets.append(target.GetName())
    return build_targets

  def GetTargets(self):
    """ returns list of CoverageTarget"""
    return self._target_map.values()

  def GetTarget(self, name):
    """ returns CoverageTarget for given name. None if not found """
    try:
      return self._target_map[name]
    except KeyError:
      return None

  def _ParseCoverageTarget(self, target, target_element):
    """Parse coverage data from XML.

    Args:
      target: the Coverage object to populate
      target_element: the XML element to get data from
    """
    target.SetName(target_element.getAttribute(self._NAME_ATTR))
    target.SetType(target_element.getAttribute(self._TYPE_ATTR))
    target.SetBuildPath(target_element.getAttribute(self._BUILD_ATTR))
    self._paths = []
    self._ParsePaths(target, target_element)

  def _ParsePaths(self, target, target_element):
    src_elements = target_element.getElementsByTagName(self._SRC_TAG)
    if len(src_elements) <= 0:
      # no src tags specified. Assume build_path + src
      target.AddPath(os.path.join(target.GetBuildPath(), "src"))
    for src_element in src_elements:
      rel_path = src_element.getAttribute(self._PATH_ATTR)
      target.AddPath(os.path.join(target.GetBuildPath(), rel_path))


def Parse(xml_file_path):
  """parses out a file_path class from given path to xml"""
  targets = CoverageTargets()
  targets.Parse(xml_file_path)
  return targets
