# -*- coding: utf-8 -*-
from sadisplay import __version__


# by pull request
# https://bitbucket.org/estin/sadisplay/pull-requests/4/format-table-info/diff
def format_column(column):
    type, name, role = column
    role_char = {
        'pk': u'\U00002605',
        'fk': u'\U00002606',
    }.get(role, u'\U000026AA')

    return type, '%s %s' % (role_char, name)


def format_property(property_name):
    type_char = u'\U000026AA'

    return '%s %s' % (type_char, property_name)


def tabular_output(table, indent=None, col_delimiter=None):
    indent = indent or ' ' * 4
    col_delimiter = col_delimiter or ' '
    col_width = [max(len(x) for x in col) for col in zip(*table)]
    for line in table:
        yield indent + col_delimiter.join(
            '{:{}}'.format(x, col_width[i]) for i, x in enumerate(line)
        )


def plantuml(desc):
    """Generate plantuml class diagram

    :param desc: result of sadisplay.describe function

    Return plantuml class diagram string
    """

    classes, relations, inherits = desc

    result = [
        '@startuml',
        'skinparam defaultFontName Courier',
    ]

    def _cleanup(col):
        type, name = col
        return type.replace('(', '[').replace(')', ']'), name

    for cls in classes:
        # issue #11 - tabular output of class members (attrs)
        # http://stackoverflow.com/a/8356620/258194

        # build table
        class_desc = []
        # table columns
        class_desc += [
            _cleanup(format_column(i)) for i in cls['cols']
        ]
        # class properties
        class_desc += [('+', i) for i in cls['props']]
        # methods
        class_desc += [('%s()' % i, '') for i in cls['methods']]

        result.append(
            'Class %(name)s {\n%(desc)s\n}' % {
                'name': cls['name'],
                'desc': '\n'.join(tabular_output(class_desc)),
            }
        )

    for item in inherits:
        result.append("%(parent)s <|-- %(child)s" % item)

    for item in relations:
        result.append("%(from)s <--o %(to)s: %(by)s" % item)

    result += [
        'right footer generated by sadisplay v%s' % __version__,
        '@enduml',
    ]

    return '\n\n'.join(result)


def dot(desc):
    """Generate dot file

    :param desc: result of sadisplay.describe function

    Return string
    """

    classes, relations, inherits = desc

    CLASS_TEMPLATE = """
        %(name)s [label=<
        <TABLE BGCOLOR="lightyellow" BORDER="0"
            CELLBORDER="0" CELLSPACING="0">
                <TR><TD COLSPAN="2" CELLPADDING="4"
                        ALIGN="CENTER" BGCOLOR="palegoldenrod"
                ><FONT FACE="Helvetica Bold" COLOR="black"
                >%(name)s</FONT></TD></TR>%(cols)s%(props)s%(methods)s
        </TABLE>
    >]
    """

    COLUMN_TEMPLATE = """<TR><TD ALIGN="LEFT" BORDER="0"
        ><FONT FACE="Bitstream Vera Sans">%(name)s</FONT
        ></TD><TD ALIGN="LEFT"
        ><FONT FACE="Bitstream Vera Sans">%(type)s</FONT
        ></TD></TR>"""

    PROPERTY_TEMPLATE = """<TR><TD ALIGN="LEFT" BORDER="0"
        BGCOLOR="palegoldenrod"
        ><FONT FACE="Bitstream Vera Sans">%(name)s</FONT></TD
        ><TD BGCOLOR="palegoldenrod" ALIGN="LEFT"
        ><FONT FACE="Bitstream Vera Sans">PROPERTY</FONT
        ></TD></TR>"""

    METHOD_TEMPLATE = """<TR><TD ALIGN="LEFT" BORDER="0"
        BGCOLOR="palegoldenrod"
        ><FONT FACE="Bitstream Vera Sans">%(name)s()</FONT></TD
        ><TD BGCOLOR="palegoldenrod" ALIGN="LEFT"
        ><FONT FACE="Bitstream Vera Sans">METHOD</FONT
        ></TD></TR>"""

    EDGE_INHERIT = "\tedge [\n\t\tarrowhead = empty\n\t]"
    INHERIT_TEMPLATE = "\t%(child)s -> %(parent)s \n"

    EDGE_REL = "\tedge [\n\t\tarrowhead = ediamond\n\t\tarrowtail = open\n\t]"
    RELATION_TEMPLATE = "\t\"%(from)s\" -> \"%(to)s\" [label = \"%(by)s\"]"

    result = ["""
        digraph G {
            label = "generated by sadisplay v%s";
            fontname = "Bitstream Vera Sans"
            fontsize = 8

            node [
                fontname = "Bitstream Vera Sans"
                fontsize = 8
                shape = "plaintext"
            ]

            edge [
                fontname = "Bitstream Vera Sans"
                fontsize = 8
            ]
    """ % __version__]

    for cls in classes:
        cols = ' '.join([
            COLUMN_TEMPLATE % {'type': c[0], 'name': c[1]}
            for c in map(format_column, cls['cols'])
        ])
        props = ' '.join([
            PROPERTY_TEMPLATE % {'name': format_property(p)}
            for p in cls['props']
        ])
        methods = ' '.join([
            METHOD_TEMPLATE % {'name': m} for m in cls['methods']
        ])
        renderd = CLASS_TEMPLATE % {
            'name': cls['name'],
            'cols': cols,
            'props': props,
            'methods': methods,
        }

        result.append(renderd)

    result += [EDGE_INHERIT]
    for item in inherits:
        result.append(INHERIT_TEMPLATE % item)

    result += [EDGE_REL]
    for item in relations:
        result.append(RELATION_TEMPLATE % item)

    result += [
        '}'
    ]

    return '\n'.join(result)
