# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.


from ...exceptions import AriaException
from ...utils.exceptions import print_exception
from ..validation import Issue


class Consumer(object):
    """
    Base class for ARIA consumers.

    Consumers provide useful functionality by consuming presentations.
    """

    def __init__(self, context):
        self.context = context

    def consume(self):
        pass

    def dump(self):
        pass

    def _handle_exception(self, e):
        if hasattr(e, 'issue') and isinstance(e.issue, Issue):
            self.context.validation.report(issue=e.issue)
        else:
            self.context.validation.report(exception=e)
        if not isinstance(e, AriaException):
            print_exception(e)


class ConsumerChain(Consumer):
    """
    ARIA consumer chain.

    Calls consumers in order, handling exception by calling ``_handle_exception`` on them, and stops
    the chain if there are any validation issues.
    """

    def __init__(self, context, consumer_classes=None, handle_exceptions=True):
        super(ConsumerChain, self).__init__(context)
        self.handle_exceptions = handle_exceptions
        self.consumers = []
        if consumer_classes:
            for consumer_class in consumer_classes:
                self.append(consumer_class)

    def append(self, *consumer_classes):
        for consumer_class in consumer_classes:
            self.consumers.append(consumer_class(self.context))

    def consume(self):
        for consumer in self.consumers:
            try:
                consumer.consume()
            except BaseException as e:
                if self.handle_exceptions:
                    handle_exception(consumer, e)
                else:
                    raise e
            if self.context.validation.has_issues:
                break


def handle_exception(consumer, e):
    if isinstance(e, AriaException) and e.issue:
        consumer.context.validation.report(issue=e.issue)
    else:
        consumer.context.validation.report(exception=e)
    if not isinstance(e, AriaException):
        print_exception(e)
