"""Implements the conversion of the response data to valid html data.
"""

import collections
from BeautifulSoup import BeautifulSoup
from django.conf import settings
from django.http import HttpResponse
from types import NoneType


# This module uses type and isinstance in an appropriate way
# pylint: disable=unidiomatic-typecheck


def build_html(_request, response, content_type):
    """Return http response object in text/html format.
    """
    html_template = '<!DOCTYPE HTML>\n<html><body>%s</body></html>'
    if hasattr(response, 'root'):
        dom = html_template % _convert(response[response.root])
    else:
        dom = html_template % _convert(response)
    if content_type is not None:
        if not 'charset' in content_type:
            content_type += '; charset=utf-8'
    if settings.DEBUG:
        dom = BeautifulSoup(dom).prettify()
    return HttpResponse(dom, content_type, status=response['_meta']['status'])


def _convert(obj):
    """This is the recursive converter.
    """
    if type(obj) in (int, float, str, unicode, bool, NoneType):
        return _convert_atom(obj)
    if isinstance(obj, dict):
        return _convert_dict(obj)
    if type(obj) in (list, set, tuple) or isinstance(obj, collections.Iterable):
        return _convert_list(obj)
    return _convert_atom(unicode(obj))


def _convert_atom(val):
    """Return xml element for atom which are 'int', 'float',
    'long', 'string', 'boolean' and 'null'.
    """
    if type(val) is int:
        val_type = "int"
    elif type(val) is float:
        val_type = "float"
    elif type(val) in (str, unicode):
        val_type = "string"
        if val.startswith('/') or val.startswith('http:'):
            val = '<a href="%s">%s</a>' % (val, val)
        else:
            val = "<br>".join(val.split("\n"))
    elif type(val) is bool:
        val_type = "boolean"
    elif type(val) is NoneType:
        val_type = "null"
        val = ""
    else:
        raise TypeError('Unsupported data type')
    return '<span class="%s">%s</span>' % (val_type, val)


def _convert_dict(obj):
    """Return xml element for dict.
    """
    output = "<dl>"
    for k, v in obj.items():
        output += '<dt>%s</dt>' % k
        output += '<dd>%s</dd>' % _convert(v)
    output += "</dl>"
    return output


def _convert_list(items):
    """Return xml element for list.
    """
    output = "<ol>"
    for item in items:
        output += '<li>%s</li>' % _convert(item)
    output += "</ol>"
    return output
