# -*- coding: utf-8 -*-
#
# Copyright 2015 Simone Campagna
#
# 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.
#

"""
Command classes
"""


import inspect

from .alias import Alias
from .element import Element
from .command import CommandMaker
from ._internals import NHHDecorator, identity, add_space
from .documented_element import DocumentedElement
from .exceptions import CallError
from .utils import tabulate, make_title

__author__ = "Simone Campagna"
__copyright__ = 'Copyright (c) 2016 Simone Campagna'
__license__ = 'Apache License Version 2.0'

__all__ = (
    'Group',
)

# pylint: disable=too-few-public-methods


class Group(DocumentedElement):
    """Class for group of elements

    Parameters
    ----------
    name: str, optional
        the element name (defaults to ``None``)
    hidden: bool, optional
        if ``True`` the element will be hidden (defaults to ``None``)
    parent: Element, optional
        a parent element (defaults to ``None``)
    doc: str, optional
        a documentation string (default to ``None``)
    content: dict, optional
        a dictionary of initialization content
    has_arguments: bool, optional
        if True adds an argument parser
    default: str, optional
        a default child element name which is used if the Group is executed without arguments
        (defaults to ``None``)
    """
    def __init__(self, *,
                 name=None, hidden=None, parent=None, doc=None, content=None,
                 has_arguments=True, default=None):
        super().__init__(name=name, hidden=hidden, parent=parent,
                         doc=doc, content=content, has_arguments=has_arguments)
        self._default = default
        for name, element in self._class_content():
            name = element.name or name
            if name not in self._content:
                self.add_content(element, name=name)

    def add_content(self, element, name=None):
        if isinstance(element, str):
            element = self.alias(target=element, name=name)
        return super().add_content(element, name=name)

    @property
    def default(self):
        "Get the default"
        return self._default

    @default.setter
    def default(self, value):
        "Set the default"
        self._default = value

    @property
    def content(self):
        """Return a copy of the content dictionary

        Returns
        -------
        OrderedDict
            a ``{name: element}`` dictionary
        """
        return self._content.copy()

    def _copy_post_hook(self, obj):
        obj.default = self._default
        super()._copy_post_hook(obj)

    @classmethod
    def _class_content(cls):
        """Iterator over (name, element)

        Yields
        ------