"""Converts performance data files (as produced by utils.py) to LaTeX charts."""

import utils

# Generated LaTeX is based on the accepted answer to
# http://tex.stackexchange.com/questions/101320/grouped-bar-chart

# pylint: disable=I0011,W0141

LATEX_COLORS = [
    ('chartBlue', 0x4F81BD),
    ('chartRed', 0xC0504D),
    ('chartGreen', 0x9BBB59),
    ('chartPurple', 0x9F4C7C),
    ('chartDarkYellow', 0xCCCC00)
]

LATEX_HEADER = r"""\documentclass[12pt,a4paper,onecolumn,openright]{report}
\usepackage{xcolor}
\usepackage{pgfplots}
\usepackage{tikz}
\usepgfplotslibrary{units}

% Define bar chart colors
%"""

LATEX_DOCUMENT_HEADER = r"""\begin{document}
\begin{tikzpicture}"""

LATEX_DOCUMENT_FOOTER = r"""\end{tikzpicture}
\end{document}"""

def encode_latex_string(value):
    """Encodes the given string as a LaTeX string."""
    # I guess this is good enough for now. This may need to be
    # revisited if we encounter more complicated names.
    return '{%s}' % value.replace('_', '\\_')

def assemble_latex_chart(optimization_levels, color_defs, test_names, data):
    """Assembles a LaTeX chart from the given components."""
    lines = []
    lines.append(LATEX_HEADER)
    for color in color_defs:
        lines.append(r'\definecolor{%s}{HTML}{%X}' % color)
    lines.append(LATEX_DOCUMENT_HEADER)
    lines.append(r"""
    \begin{axis}[
        width = 0.85*\textwidth,
        height = 8cm,
        major x tick style = transparent,
        ybar=2*\pgflinewidth,
        bar width=14pt,
        ymajorgrids = true,
        ylabel = {Run time},
        symbolic x coords={%s},
        xtick = data,
        scaled y ticks = false,
        enlarge x limits=0.25,
        ymin=0,
        y unit=s,
        legend cell align=left,
        legend style={
                at={(1,1.05)},
                anchor=south east,
                column sep=1ex
        }
    ]""" % ','.join(map(encode_latex_string, test_names)))
    for color_name, points in data:
        lines.append(r"""
        \addplot[style={%s,fill=%s,mark=none}]
            coordinates {%s};""" % (
                color_name, color_name,
                ' '.join([('(%s,%s)' % (encode_latex_string(name), measurement))
                          for name, measurement in points])))
    lines.append(r"""
        \legend{%s}""" % ','.join(map(encode_latex_string, optimization_levels)))
    lines.append(r"""
    \end{axis}""")
    lines.append(LATEX_DOCUMENT_FOOTER)
    return '\n'.join(lines)

def create_latex_chart(perf_data):
    """Creates a LaTeX chart for the given performance data."""
    unused_colors = LATEX_COLORS[:]
    opt_levels = []
    color_defs = []
    test_names = []
    data = []
    for optimization_level, measurements in perf_data:
        color = unused_colors.pop(0)
        color_name, _ = color
        opt_levels.append(optimization_level)
        color_defs.append(color)
        data.append((color_name, measurements))
        for name, _ in measurements:
            if name not in test_names:
                test_names.append(name)

    return assemble_latex_chart(opt_levels, color_defs, test_names, data)

if __name__ == '__main__':
    print(create_latex_chart(utils.parse_perf_data(utils.DEFAULT_PERF_FILE_NAME)))
