#
# 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.
#

"""This file provides all Packs element related parsing."""


from project import collection
from project import common
from project import loader
from project import pack


class PacksFactory(object):
    @staticmethod
    def new(**kwargs):
        """Creates a new Packs instance from an XML file or element.

        Walks an ElementTree element looking for <pack> child
        nodes and instantiates Pack objects.

        Args:
            **kwargs: Any valid keywords for loader.PathElementLoader.load()

        Returns:
            new Packs() instance

        Raises
            LoadError: LoadError, or a subclass, will be raised if an error
                occurs loading and validating content from the XML.
        """
        ps = Packs()
        l = loader.PathElementLoader('packs', ['namespace'])
        # Get the final root node.
        root = l.load(**kwargs)
        root.limit_attribs(['version', 'namespace', 'path'])
        ps.namespace = root.get_attrib('namespace')
        ns = ps.namespace
        # pylint: disable=no-member
        if 'namespace' in root.old_attrib:
            ns = root.old_attrib['namespace']

        packs = {}
        for node in root.findall('pack'):
            name = node.get_attrib('name')
            if name in packs:
                # Note, this only catch duplication within the same
                # packs tree. As packs namespaces are non-unique, collision
                # can occur when aggregating packs.
                raise common.LoadErrorWithOrigin(
                    node,
                    'Duplicate pack {} in namespace {}'.format(name,
                                                               ps.namespace))
            p = pack.Pack(ns, name)
            p.load(node)
            # Even if 'namespace' is carried over in the root attributes, we
            # have to alias any global requires/provides in the pack.
            if ns != ps.namespace:
                p.alias(ps.namespace)
            packs[name] = p

        ps.entries = packs
        ps.origins = l.origins
        return ps


class Packs(collection.Base):
    """Collection of Pack objects."""
    def __init__(self):
        super(Packs, self).__init__('packs')
        self._namespace = ()

    @property
    def packs(self):
        return self.entries

    @property
    def namespace(self):
        """Return the namespace for all child pack objects."""
        return self._namespace

    @namespace.setter
    def namespace(self, ns):
        for pack_ in self._entries.values():
            pack_.alias(ns)
        self._namespace = ns

    def add_pack(self, new_pack):
        if new_pack.name in self.entries:
            # Note, this only catch duplication within the same
            # packs tree. As packs namespaces are non-unique, collision
            # can occur when aggregating packs.
            raise common.LoadErrorWithOrigin(
                new_pack.origin,
                'Duplicate pack {} in namespace {}'.format(new_pack.name,
                                                           self.namespace))
        self.entries[new_pack.name] = new_pack


    def __repr__(self):
        return '<packs namespace="{}">{}</packs>'.format(
            self._namespace, ''.join([str(p) for p in self._entries.values()]))
