# Copyright 2021-2024 Teemu Ikonen
# SPDX-License-Identifier: GPL-3.0-only

def text_barchart(data, highlights, height=None, width=30):
    """Return a string with a bar chart rendered as text.

    data:   Iterable of (label, value) tuples
    highlights: List/set of labels for which the bar is highlighted
    height  Number of lines in the generated bar chart
    width   Width of the generated bar chart in chars
    """
    sdata = [(d[0] if d[0] else '', int(d[1]) if d[1] else 0) for d in data]
    sdata.sort(key=lambda x: x[1], reverse=True)

    dstr = ''
    axislines = 2  # x-axis needs this many lines
    height = height if height is not None else len(sdata) + axislines
    if (len(sdata) + axislines) < height:
        barlines = len(sdata)
#        # Add empty lines in the beginning
#        dstr += '\n' * (height - len(sdata) - axislines)
    else:
        barlines = height - axislines - 1

    xextra = 7  # Non-block chars in longest line
    max_x = max(x[1] for x in sdata) if sdata else 0
    xstep = 5  # xaxis grows by this step
    max_xaxis = xstep * ((max_x + xstep) // xstep)
    cmaxbar = width - xextra
    scale = cmaxbar / max_x if max_x > 0 else 1.0
    cmax_xaxis = cmaxbar + 3
    for d in sdata[:barlines]:
        block = '\u2585' if d[0] in highlights else '='
        dstr += "%3s\u2502%s %d\n" % (d[0], block * int(scale * d[1]), d[1])
    if barlines < len(sdata):
        dstr += "   \u256a\n"
    elif (len(sdata) - axislines) < height:
        # Add empty lines to y-axis
        dstr += '   \u2502\n' * (height - len(sdata) - axislines)
    dstr += "   \u251c" + '\u2500' * (cmax_xaxis) + '\u2524\n'
    dstr += "   0" + ' ' * (cmax_xaxis - 1) + str(max_xaxis)
    return dstr
