"""OpenAPI core responses generators module"""
from six import iteritems

from openapi_core.compat import lru_cache
from openapi_core.schema.content.factories import ContentFactory
from openapi_core.schema.extensions.generators import ExtensionsGenerator
from openapi_core.schema.links.generators import LinksGenerator
from openapi_core.schema.parameters.generators import ParametersGenerator
from openapi_core.schema.responses.models import Response


class ResponsesGenerator(object):

    def __init__(self, dereferencer, schemas_registry):
        self.dereferencer = dereferencer
        self.schemas_registry = schemas_registry

    def generate(self, responses):
        for http_status, response in iteritems(responses):
            response_deref = self.dereferencer.dereference(response)
            description = response_deref['description']
            headers = response_deref.get('headers')
            content_spec = response_deref.get('content')
            links_dict = response_deref.get('links', {})
            links = self.links_generator.generate(links_dict)

            extensions = self.extensions_generator.generate(response_deref)

            content = None
            if content_spec:
                content = self.content_factory.create(content_spec)

            parameters = None
            if headers:
                parameters = self.parameters_generator.generate(headers)

            yield http_status, Response(
                http_status, description,
                content=content, headers=parameters, links=links,
                extensions=extensions,
            )

    @property
    @lru_cache()
    def content_factory(self):
        return ContentFactory(self.dereferencer, self.schemas_registry)

    @property
    @lru_cache()
    def parameters_generator(self):
        return ParametersGenerator(self.dereferencer, self.schemas_registry)

    @property
    @lru_cache()
    def links_generator(self):
        return LinksGenerator(self.dereferencer, self.schemas_registry)

    @property
    @lru_cache()
    def extensions_generator(self):
        return ExtensionsGenerator(self.dereferencer)
