#
# Copyright (C) 2016 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.

"""Wraps nested XML file loading for specific elements."""

import os

from project import common
from project import xml_parser


class PathElementLoader(object):
    """Processes an XML element node with either a 'path' attribute
    or child nodes.  All attributes in the attrib_rollover list
    will be propagated down to the final returned root node.
    """
    def __init__(self, tag, rollover_attribs):
        self._tag = tag
        self._rollover_names = rollover_attribs
        self._rollover_attribs = {}
        # List of origins for any parsed @tag
        # nodes.  This is only a list because
        # @tag may load a different @tag node.
        self._origins = []

    @property
    def origins(self):
        """Return the list of Origin objects parsed for this loader."""
        return self._origins

    def load(self, **source):
        """Populates the instance from an XML file or element.

        Dereferences elements that may include other files returning
        the final defined element.

        Args:
            **source: May have one of the following keys set:
            - 'path': The path (str) to a file to open, read, and parse.
            - 'file': A file-compatible object to read from for parsing.
            - 'element': Provides the root element node to walk.

        Returns:
            Actual root node with overridden rollover attributes and
            a new 'old_attribs' attribute containing the most recent root node's
            original values.

        Raises
            LoadError: LoadError, or a subclass, will be raised if an error
                occurs loading and validating content from the XML.
        """
        ALLOWED_KEYS = ('path', 'file', 'element')
        if len(source) != 1 or source.keys()[0] not in ALLOWED_KEYS:
            raise ValueError(
                'Exactly one of {} must be supplied: {}'.format(ALLOWED_KEYS,
                                                                source))
        if 'element' in source:
            return self._load_element(source['element'])

        src = ''
        if 'path' in source:
            src = os.path.abspath(source['path'])
        elif 'file' in source:
            src = source['file']
        root = self._load_file(src)
        if root is None:
            raise common.LoadError(
                'Failed to access and read file: {}'.format(src))
        return root

    def _load_file(self, f):
        seen = [x for x in self._origins if x.source_file == f]
        if len(seen):
            # Break cycles: A -> B -> A
            print 'Warning: path "{}" included more than once.'.format(f)
            return None
        try:
            tree = xml_parser.parse(f)
        except IOError:
            return None
        root = tree.getroot()
        if root.tag != self._tag:
            # pylint: disable=no-member
            raise common.LoadErrorWithOrigin(
                root.origin,
                'Included file "{}" root node is not a <{}>'.format(f,
                                                                    self._tag))
        return self._load_element(root)

    def _load_element(self, root):
        self._origins += [root.origin.copy()]
        # Overwrite any attribs from rollover_attribs.
        root.old_attrib = {}
        for attr in self._rollover_attribs:
            if attr in root.attrib:
                root.old_attrib[attr] = root.attrib[attr]
                root.attrib[attr] = self._rollover_attribs[attr]
        # Copy out any attribs that should rollover.
        for attr in root.attrib:
            if attr in self._rollover_names:
                self._rollover_attribs[attr] = root.attrib[attr]
        if 'path' in root.attrib:
            path = root.get_attrib('path')
            # Resolve relative paths using the including file's path.
            if path[0] != '/':
                caller = root.origin.source_file
                path = os.path.join(os.path.dirname(caller), path)
            # Populate internal state from the given path.
            new_root = self._load_file(path)
            if new_root is None:
                raise common.LoadErrorWithOrigin(
                    root.origin,
                    'Unable to load <{}> from file: {}'.format(self._tag, path))
            return new_root
        return root
