#!/usr/bin/env python

# Copyright (C) 2011 by Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
# Copyright (C) 2013 by Yann E. MORIN <yann.morin.1998@free.fr>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

# This script generates graphs of packages build time, from the timing
# data generated by Buildroot in the $(O)/build-time.log file.
#
# Example usage:
#
#   cat $(O)/build-time.log | ./support/scripts/graph-build-time --type=histogram --output=foobar.pdf
#
# Three graph types are available :
#
#   * histogram, which creates an histogram of the build time for each
#     package, decomposed by each step (extract, patch, configure,
#     etc.). The order in which the packages are shown is
#     configurable: by package name, by build order, or by duration
#     order. See the --order option.
#
#   * pie-packages, which creates a pie chart of the build time of
#     each package (without decomposition in steps). Packages that
#     contributed to less than 1% of the overall build time are all
#     grouped together in an "Other" entry.
#
#   * pie-steps, which creates a pie chart of the time spent globally
#     on each step (extract, patch, configure, etc...)
#
# The default is to generate an histogram ordered by package name.
#
# Requirements:
#
#   * matplotlib (python-matplotlib on Debian/Ubuntu systems)
#   * numpy (python-numpy on Debian/Ubuntu systems)
#   * argparse (by default in Python 2.7, requires python-argparse if
#     Python 2.6 is used)

import sys

try:
    import matplotlib as mpl
    import numpy
except ImportError:
    sys.stderr.write("You need python-matplotlib and python-numpy to generate build graphs\n")
    exit(1)

# Use the Agg backend (which produces a PNG output, see
# http://matplotlib.org/faq/usage_faq.html#what-is-a-backend),
# otherwise an incorrect backend is used on some host machines).
# Note: matplotlib.use() must be called *before* matplotlib.pyplot.
mpl.use('Agg')

import matplotlib.pyplot as plt       # noqa: E402
import matplotlib.font_manager as fm  # noqa: E402
import csv                            # noqa: E402
import argparse                       # noqa: E402

steps = ['download', 'extract', 'patch', 'configure', 'build',
         'install-target', 'install-staging', 'install-images',
         'install-host']

default_colors = ['#8d02ff', '#e60004', '#009836', '#2e1d86', '#ffed00',
                  '#0068b5', '#f28e00', '#940084', '#97c000']

alternate_colors = ['#ffbe0a', '#96bdff', '#3f7f7f', '#ff0000', '#00c000',
                    '#0080ff', '#c000ff', '#00eeee', '#e0e000']


class Package:
    def __init__(self, name):
        self.name = name
        self.steps_duration = {}
        self.steps_start = {}
        self.steps_end = {}

    def add_step(self, step, state, time):
        if state == "start":
            self.steps_start[step] = time
        else:
            self.steps_end[step] = time
        if step in self.steps_start and step in self.steps_end:
            self.steps_duration[step] = self.steps_end[step] - self.steps_start[step]

    def get_duration(self, step=None):
        if step is None:
            duration = 0
            for step in list(self.steps_duration.keys()):
                duration += self.steps_duration[step]
            return duration
        if step in self.steps_duration:
            return self.steps_duration[step]
        return 0


# Generate an histogram of the time spent in each step of each
# package.
def pkg_histogram(data, output, order="build"):
    n_pkgs = len(data)
    ind = numpy.arange(n_pkgs)

    if order == "duration":
        data = sorted(data, key=lambda p: p.get_duration(), reverse=True)
    elif order == "name":
        data = sorted(data, key=lambda p: p.name, reverse=False)

    # Prepare the vals array, containing one entry for each step
    vals = []
    for step in steps:
        val = []
        for p in data:
            val.append(p.get_duration(step))
        vals.append(val)

    bottom = [0] * n_pkgs
    legenditems = []

    plt.figure()

    # Draw the bars, step by step
    for i in range(0, len(vals)):
        b = plt.bar(ind+0.1, vals[i], width=0.8, color=colors[i], bottom=bottom, linewidth=0.25)
        legenditems.append(b[0])
        bottom = [bottom[j] + vals[i][j] for j in range(0, len(vals[i]))]

    # Draw the package names
    plt.xticks(ind + .6, [p.name for p in data], rotation=-60, rotation_mode="anchor", fontsize=8, ha='left')

    # Adjust size of graph depending on the number of packages
    # Ensure a minimal size twice as the default
    # Magic Numbers do Magic Layout!
    ratio = max(((n_pkgs + 10) / 48, 2))
    borders = 0.1 / ratio
    sz = plt.gcf().get_figwidth()
    plt.gcf().set_figwidth(sz * ratio)

    # Adjust space at borders, add more space for the
    # package names at the bottom
    plt.gcf().subplots_adjust(bottom=0.2, left=borders, right=1-borders)

    # Remove ticks in the graph for each package
    axes = plt.gcf().gca()
    for line in axes.get_xticklines():
        line.set_markersize(0)

    axes.set_ylabel('Time (seconds)')

    # Reduce size of legend text
    leg_prop = fm.FontProperties(size=6)

    # Draw legend
    plt.legend(legenditems, steps, prop=leg_prop)

    if order == "name":
        plt.title('Build time of packages\n')
    elif order == "build":
        plt.title('Build time of packages, by build order\n')
    elif order == "duration":
        plt.title('Build time of packages, by duration order\n')

    # Save graph
    plt.savefig(output)


# Generate a pie chart with the time spent building each package.
def pkg_pie_time_per_package(data, output):
    # Compute total build duration
    total = 0
    for p in data:
        total += p.get_duration()

    # Build the list of labels and values, and filter the packages
    # that account for less than 1% of the build time.
    labels = []
    values = []
    other_value = 0
    for p in sorted(data, key=lambda p: p.get_duration()):
        if p.get_duration() < (total * 0.01):
            other_value += p.get_duration()
        else:
            labels.append(p.name)
            values.append(p.get_duration())

    labels.append('Other')
    values.append(other_value)

    plt.figure()

    # Draw pie graph
    patches, texts, autotexts = plt.pie(values, labels=labels,
                                        autopct='%1.1f%%', shadow=True,
                                        colors=colors)

    # Reduce text size
    proptease = fm.FontProperties()
    proptease.set_size('xx-small')
    plt.setp(autotexts, fontproperties=proptease)
    plt.setp(texts, fontproperties=proptease)

    plt.title('Build time per package')
    plt.savefig(output)


# Generate a pie chart with a portion for the overall time spent in
# each step for all packages.
def pkg_pie_time_per_step(data, output):
    steps_values = []
    for step in steps:
        val = 0
        for p in data:
            val += p.get_duration(step)
        steps_values.append(val)

    plt.figure()

    # Draw pie graph
    patches, texts, autotexts = plt.pie(steps_values, labels=steps,
                                        autopct='%1.1f%%', shadow=True,
                                        colors=colors)

    # Reduce text size
    proptease = fm.FontProperties()
    proptease.set_size('xx-small')
    plt.setp(autotexts, fontproperties=proptease)
    plt.setp(texts, fontproperties=proptease)

    plt.title('Build time per step')
    plt.savefig(output)


# Parses the csv file passed on standard input and returns a list of
# Package objects, filed with the duration of each step and the total
# duration of the package.
def read_data(input_file):
    if input_file is None:
        input_file = sys.stdin
    else:
        input_file = open(input_file)
    reader = csv.reader(input_file, delimiter=':')
    pkgs = []

    # Auxilliary function to find a package by name in the list.
    def getpkg(name):
        for p in pkgs:
            if p.name == name:
                return p
        return None

    for row in reader:
        time = float(row[0].strip())
        state = row[1].strip()
        step = row[2].strip()
        pkg = row[3].strip()

        p = getpkg(pkg)
        if p is None:
            p = Package(pkg)
            pkgs.append(p)

        p.add_step(step, state, time)

    return pkgs


parser = argparse.ArgumentParser(description='Draw build time graphs')
parser.add_argument("--type", '-t', metavar="GRAPH_TYPE",
                    help="Type of graph (histogram, pie-packages, pie-steps)")
parser.add_argument("--order", '-O', metavar="GRAPH_ORDER",
                    help="Ordering of packages: build or duration (for histogram only)")
parser.add_argument("--alternate-colors", '-c', action="store_true",
                    help="Use alternate colour-scheme")
parser.add_argument("--input", '-i', metavar="INPUT",
                    help="Input file (usually $(O)/build/build-time.log)")
parser.add_argument("--output", '-o', metavar="OUTPUT", required=True,
                    help="Output file (.pdf or .png extension)")
args = parser.parse_args()

d = read_data(args.input)

if args.alternate_colors:
    colors = alternate_colors
else:
    colors = default_colors

if args.type == "histogram" or args.type is None:
    if args.order == "build" or args.order == "duration" or args.order == "name":
        pkg_histogram(d, args.output, args.order)
    elif args.order is None:
        pkg_histogram(d, args.output, "name")
    else:
        sys.stderr.write("Unknown ordering: %s\n" % args.order)
        exit(1)
elif args.type == "pie-packages":
    pkg_pie_time_per_package(d, args.output)
elif args.type == "pie-steps":
    pkg_pie_time_per_step(d, args.output)
else:
    sys.stderr.write("Unknown type: %s\n" % args.type)
    exit(1)
