#!/usr/bin/env python
# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Parses perf data files and creates chrome-based graph files from that data.

This script assumes that extract_perf.py was previously run to extract perf
test data from a database and then dump it into local text data files.  This
script then parses the extracted perf data files and creates new data files that
can be directly read in by chrome's perf graphing infrastructure to display
perf graphs.

This script also generates a set of Javascript/HTML overview pages that present
birds-eye overviews of multiple perf graphs simultaneously.

Sample usage:
  python generate_perf_graphs.py -c -v

Run with -h to see the full set of command-line options.

"""

import fnmatch
import logging
import math
import optparse
import os
import re
import shutil
import json
import sys
import urllib
import urllib2

_SETTINGS = 'autotest_lib.frontend.settings'
os.environ['DJANGO_SETTINGS_MODULE'] = _SETTINGS

import common
from django.shortcuts import render_to_response

_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
_CHART_CONFIG_FILE = os.path.join(_SCRIPT_DIR, 'croschart_defaults.json')
_TEMPLATE_DIR = os.path.join(_SCRIPT_DIR, 'templates')
_CURR_PID_FILE_NAME = __file__ + '.curr_pid.txt'
_COMPLETED_ID_FILE_NAME = 'job_id_complete.txt'
_REV_NUM_FILE_NAME = 'rev_num.txt'
_WILDCARD = '*'
_TELEMETRY_PERF_KEY_IDENTIFIER = 'TELEMETRY'
_TELEMETRY_PERF_KEY_DELIMITER = '--'
_NEW_DASH_UPLOAD_URL = 'https://chromeperf.appspot.com/add_point'

# Values that can be configured through options.
# TODO(dennisjeffrey): Infer the tip-of-tree milestone dynamically once this
# issue is addressed: crosbug.com/38564.
_TOT_MILESTONE = 27
_OLDEST_MILESTONE_TO_GRAPH = 25
_DATA_DIR = _SCRIPT_DIR
_GRAPH_DIR = _SCRIPT_DIR

# Other values that can only be configured here in the code.
_SYMLINK_LIST = [
    ('report.html',   '../../../../ui/cros_plotter.html'),
    ('js',            '../../../../ui/js'),
]


def set_world_read_permissions(path):
    """Recursively sets the content of |path| to be world-readable.

    @param path: The string path.

    """
    logging.debug('Setting world-read permissions recursively on %s', path)
    os.chmod(path, 0755)
    for root, dirs, files in os.walk(path):
        for d in dirs:
            dname = os.path.join(root, d)
            if not os.path.islink(dname):
                os.chmod(dname, 0755)
        for f in files:
            fname = os.path.join(root, f)
            if not os.path.islink(fname):
                os.chmod(fname, 0755)


def remove_path(path):
    """Remove the given path (whether file or directory).

    @param path: The string path.

    """
    if os.path.isdir(path):
        shutil.rmtree(path)
        return
    try:
        os.remove(path)
    except OSError:
        pass


def symlink_force(link_name, target):
    """Create a symlink, accounting for different situations.

    @param link_name: The string name of the link to create.
    @param target: The string destination file to which the link should point.

    """
    try:
        os.unlink(link_name)
    except EnvironmentError:
        pass
    try:
        os.symlink(target, link_name)
    except OSError:
        remove_path(link_name)
        os.symlink(target, link_name)


def mean_and_standard_deviation(data):
    """Compute the mean and standard deviation of a list of numbers.

    @param data: A list of numerica values.

    @return A 2-tuple (mean, standard_deviation) computed from |data|.

    """
    n = len(data)
    if n == 0:
        return 0.0, 0.0
    mean = float(sum(data)) / n
    if n == 1:
        return mean, 0.0
    # Divide by n-1 to compute "sample standard deviation".
    variance = sum([(element - mean) ** 2 for element in data]) / (n - 1)
    return mean, math.sqrt(variance)


def get_release_from_jobname(jobname):
    """Identifies the release number components from an autotest job name.

    For example:
        'lumpy-release-R21-2384.0.0_pyauto_perf' becomes (21, 2384, 0, 0).

    @param jobname: The string name of an autotest job.

    @return The 4-tuple containing components of the build release number, or
        None if those components cannot be identifies from the |jobname|.

    """
    prog = re.compile('r(\d+)-(\d+).(\d+).(\d+)')
    m = prog.search(jobname.lower())
    if m:
        return (int(m.group(1)), int(m.group(2)), int(m.group(3)),
                int(m.group(4)))
    return None


def is_on_mainline_of_milestone(jobname, milestone):
    """Determines whether an autotest build is on mainline of a given milestone.

    @param jobname: The string name of an autotest job (containing release
        number).
    @param milestone: The integer milestone number to consider.

    @return True, if the given autotest job name is for a release number that
        is either (1) an ancestor of the specified milestone, or (2) is on the
        main branch line of the given milestone.  Returns False otherwise.

    """
    r = get_release_from_jobname(jobname)
    m = milestone
    # Handle garbage data that might exist.
    if any(item < 0 for item in r):
        raise Exception('Unexpected release info in job name: %s' % jobname)
    if m == r[0]:
        # Yes for jobs from the specified milestone itself.
        return True
    if r[0] < m and r[2] == 0 and r[3] == 0:
        # Yes for jobs from earlier milestones that were before their respective
        # branch points.
        return True
    return False


# TODO(dennisjeffrey): Determine whether or not we need all the values in the
# config file.  Remove unnecessary ones and revised necessary ones as needed.
def create_config_js_file(path, test_name):
    """Creates a configuration file used by the performance graphs.

    @param path: The string path to the directory in which to create the file.
    @param test_name: The string name of the test associated with this config
        file.

    """
    config_content = render_to_response(
        os.path.join(_TEMPLATE_DIR, 'config.js'), locals()).content
    with open(os.path.join(path, 'config.js'), 'w') as f:
        f.write(config_content)


def chart_key_matches_actual_key(chart_key, actual_key):
    """Whether a chart key (with possible wildcard) matches a given actual key.

    A perf key in _CHART_CONFIG_FILE may have wildcards specified to match
    multiple actual perf keys that a test may measure.  For example, the
    chart key "metric*" could match 3 different actual perf keys: "meticA",
    "metricB", and "metricC".  Wildcards are specified with "*" and may occur
    in any of these formats:
      1) *metric: Matches perf keys that end with "metric".
      2) metric*: Matches perf keys that start with "metric".
      3) *metric*: Matches perf keys that contain "metric".
      4) metric:  Matches only the perf key "metric" (exact match).
      5) *: Matches any perf key.

    This function determines whether or not a given chart key (with possible
    wildcard) matches a given actual key.

    @param chart_key: The chart key string with possible wildcard.
    @param actual_key: The actual perf key.

    @return True, if the specified chart key matches the actual key, or
        False otherwise.

    """
    if chart_key == _WILDCARD:
        return True
    elif _WILDCARD not in chart_key:
        return chart_key == actual_key
    elif chart_key.startswith(_WILDCARD) and chart_key.endswith(_WILDCARD):
        return chart_key[len(_WILDCARD):-len(_WILDCARD)] in actual_key
    elif chart_key.startswith(_WILDCARD):
        return actual_key.endswith(chart_key[len(_WILDCARD):])
    elif chart_key.endswith(_WILDCARD):
        return actual_key.startswith(chart_key[:-len(_WILDCARD)])

    return False


def upload_to_chrome_dashboard(data_point_info, platform, test_name,
                               master_name):
    """Uploads a set of perf values to Chrome's perf dashboard.

    @param data_point_info: A dictionary containing information about perf
        data points to plot: key names and values, chrome(OS) version numbers.
    @param platform: The string name of the associated platform.
    @param test_name: The string name of the associated test.
    @param master_name: The string name of the "buildbot master" to use
        (a concept that exists in Chrome's perf dashboard).

    """

    # Only upload Telemetry results right now (not ChromeOS-specific results).
    # TODO(dennisjeffrey): Remove the check below as soon as we're ready to
    # upload the full suite of perf results to the new dashboard.  The check is
    # only in place temporarily to allow a subset of results to be uploaded
    # until we're ready to upload everything.
    if not test_name.startswith('telemetry_Benchmarks'):
        return

    # Generate a warning and return if any expected values in |data_point_info|
    # are missing.
    for expected_val in ['chrome_ver', 'traces', 'ver']:
        if (expected_val not in data_point_info or
            not data_point_info[expected_val]):
            logging.warning('Did not upload data point for test "%s", '
                            'platform "%s": missing value for "%s"',
                            test_name, platform, expected_val)
            return

    traces = data_point_info['traces']
    for perf_key in traces:
        perf_val = traces[perf_key][0]
        perf_err = traces[perf_key][1]

        units = None
        test_path = test_name
        if perf_key.startswith(_TELEMETRY_PERF_KEY_IDENTIFIER):
            # The perf key is associated with a Telemetry test, and has a
            # specially-formatted perf key that encodes a graph_name,
            # trace_name, and units.  Example Telemetry perf key:
            # "TELEMETRY--DeltaBlue--DeltaBlue--score__bigger_is_better_"
            graph_name, trace_name, units = (
                perf_key.split(_TELEMETRY_PERF_KEY_DELIMITER)[1:])

            # The Telemetry test name is the name of the tag that has been
            # appended to |test_name|.  For example, autotest name
            # "telemetry_Benchmarks.octane" corresponds to Telemetry test name
            # "octane" on chrome's new perf dashboard.
            test_name = test_name[test_name.find('.') + 1:]

            # Transform the names according to rules set by the Chrome team,
            # as implemented in:
            # chromium/tools/build/scripts/slave/results_dashboard.py
            if trace_name == graph_name + '_ref':
                trace_name = 'ref'
            graph_name = graph_name.replace('_by_url', '')
            trace_name = trace_name.replace('/', '_')
            test_path = '%s/%s/%s' % (test_name, graph_name, trace_name)
            if graph_name == trace_name:
                test_path = '%s/%s' % (test_name, graph_name)

        new_dash_entry = {
            'master': master_name,
            'bot': 'cros-' + platform,  # Prefix to make clear it's chromeOS.
            'test': test_path,
            'value': perf_val,
            'error': perf_err,
            'supplemental_columns': {
                'r_cros_version': data_point_info['ver'],
                'r_chrome_version': data_point_info['chrome_ver'],
            }
        }
        if units:
            new_dash_entry['units'] = units
        json_string = json.dumps([new_dash_entry], indent=2)
        params = urllib.urlencode({'data': json_string})
        fp = None
        try:
            fp = urllib2.urlopen(_NEW_DASH_UPLOAD_URL, params)
            errors = fp.read().strip()
            if errors:
                raise urllib2.URLError(errors)
        except urllib2.URLError, e:
            # TODO(dennisjeffrey): If the live dashboard is currently down,
            # cache results and retry them later when the live dashboard is
            # back up.  For now we skip the current upload if the live
            # dashboard is down.
            logging.exception('Error uploading to new dashboard, skipping '
                              'upload attempt: %s', e)
            return
        finally:
            if fp:
                fp.close()


def output_graph_data_for_entry(test_name, master_name, graph_name, job_name,
                                platform, chrome_ver, units, better_direction,
                                url, perf_keys, chart_keys, options,
                                summary_id_to_rev_num, output_data_dir):
    """Outputs data for a perf test result into appropriate graph data files.

    @param test_name: The string name of a test.
    @param master_name: The name of the "buildbot master" to use when uploading
        perf results to chrome's perf dashboard.
    @param graph_name: The string name of the graph associated with this result.
    @param job_name: The string name of the autotest job associated with this
        test result.
    @param platform: The string name of the platform associated with this test
        result.
    @param chrome_ver: The string Chrome version number associated with this
        test result.
    @param units: The string name of the units displayed on this graph.
    @param better_direction: A String representing whether better perf results
        are those that are "higher" or "lower".
    @param url: The string URL of a webpage docuementing the current graph.
    @param perf_keys: A list of 2-tuples containing perf keys measured by the
        test, where the first tuple element is a string key name, and the second
        tuple element is the associated numeric perf value.
    @param chart_keys: A list of perf key names that need to be displayed in
        the current graph.
    @param options: An optparse.OptionParser options object.
    @param summary_id_to_rev_num: A dictionary mapping a string (representing
        a test/platform/release combination), to the next integer revision
        number to use in the graph data file.
    @param output_data_dir: A directory in which to output data files.

    """
    # A string ID that is assumed to be unique across all charts.
    test_id = test_name + '__' +  graph_name

    release_num = get_release_from_jobname(job_name)
    if not release_num:
        logging.warning('Could not obtain release number for job name: %s',
                        job_name)
        return
    build_num = '%d.%d.%d.%d' % (release_num[0], release_num[1], release_num[2],
                                 release_num[3])

    # Filter out particular test runs that we explicitly do not want to
    # consider.
    # TODO(dennisjeffrey): Figure out a way to eliminate the need for these
    # special checks: crosbug.com/36685.
    if test_name == 'platform_BootPerfServer' and 'perfalerts' not in job_name:
        # Skip platform_BootPerfServer test results that do not come from the
        # "perfalerts" runs.
        return

    # Consider all releases for which this test result may need to be included
    # on a graph.
    start_release = max(release_num[0], options.oldest_milestone)
    for release in xrange(start_release, options.tot_milestone + 1):
        output_path = os.path.join(output_data_dir, 'r%d' % release, platform,
                                   test_id)
        summary_file = os.path.join(output_path, graph_name + '-summary.dat')

        # Set up the output directory if it doesn't already exist.
        if not os.path.exists(output_path):
            os.makedirs(output_path)

            # Create auxiliary files.
            create_config_js_file(output_path, test_name)
            open(summary_file, 'w').close()
            graphs = [{
              'name': graph_name,
              'units': units,
              'better_direction': better_direction,
              'info_url': url,
              'important': False,
            }]
            with open(os.path.join(output_path, 'graphs.dat'), 'w') as f:
                f.write(json.dumps(graphs, indent=2))

            # Add symlinks to the plotting code.
            for slink, target in _SYMLINK_LIST:
                slink = os.path.join(output_path, slink)
                symlink_force(slink, target)

        # Write data to graph data file if it belongs in the current release.
        if is_on_mainline_of_milestone(job_name, release):
            entry = {}
            entry['traces'] = {}
            entry['ver'] = build_num
            entry['chrome_ver'] = chrome_ver

            key_to_vals = {}
            for perf_key in perf_keys:
                if any([chart_key_matches_actual_key(c, perf_key[0])
                        for c in chart_keys]):
                    key = perf_key[0]
                    if key not in key_to_vals:
                        key_to_vals[key] = []
                    # There are some cases where results for
                    # platform_BootPerfServer are negative in reboot/shutdown
                    # times. Ignore these negative values.
                    if float(perf_key[1]) < 0.0:
                        continue
                    key_to_vals[key].append(perf_key[1])
            for key in key_to_vals:
                if len(key_to_vals[key]) == 1:
                    entry['traces'][key] = [key_to_vals[key][0], '0.0']
                else:
                    mean, std_dev = mean_and_standard_deviation(
                        map(float, key_to_vals[key]))
                    entry['traces'][key] = [str(mean), str(std_dev)]

            if entry['traces']:
                summary_id = '%s|%s|%s' % (test_id, platform, release)

                rev = summary_id_to_rev_num.get(summary_id, 0)
                summary_id_to_rev_num[summary_id] = rev + 1
                entry['rev'] = rev

                # Upload data point to the new performance dashboard (only
                # for the tip-of-tree branch).
                if release == options.tot_milestone:
                    upload_to_chrome_dashboard(entry, platform, test_name,
                                               master_name)

                # For each perf key, replace dashes with underscores so
                # different lines show up as different colors in the graphs.
                for orig_key in entry['traces'].keys():
                    new_key = orig_key.replace('-', '_')
                    entry['traces'][new_key] = entry['traces'].pop(orig_key)

                # Output data point to be displayed on the current (deprecated)
                # dashboard.
                with open(summary_file, 'a') as f:
                    f.write(json.dumps(entry) + '\n')


def process_perf_data_files(file_names, test_name, master_name, completed_ids,
                            test_name_to_charts, options,
                            summary_id_to_rev_num, output_data_dir):
    """Processes data files for a single test/platform.

    Multiple data files may exist if the given test name is associated with one
    or more old test names (i.e., the name of the test has changed over time).
    In this case, we treat all results from the specified files as if they came
    from a single test associated with the current test name.

    This function converts the data from the specified data files into new
    data files formatted in a way that can be graphed.

    @param file_names: A list of perf data files to process.
    @param test_name: The string name of the test associated with the file name
        to process.
    @param master_name: The name of the "buildbot master" to use when uploading
        perf results to chrome's perf dashboard.
    @param completed_ids: A dictionary of already-processed job IDs.
    @param test_name_to_charts: A dictionary mapping test names to a list of
        dictionaries, in which each dictionary contains information about a
        chart associated with the given test name.
    @param options: An optparse.OptionParser options object.
    @param summary_id_to_rev_num: A dictionary mapping a string (representing
        a test/platform/release combination) to an integer revision number.
    @param output_data_dir: A directory in which to output data files.

    @return The number of newly-added graph data entries.

    """
    newly_added_count = 0
    for file_name in file_names:
        with open(file_name, 'r') as fp:
            for line in fp.readlines():
                info = json.loads(line.strip())
                job_id = info[0]
                job_name = info[1]
                platform = info[2]
                chrome_ver = info[3]
                perf_keys = info[4]

                # Skip this job ID if it's already been processed.
                if job_id in completed_ids:
                    continue

                # Scan the desired charts and see if we need to output the
                # current line info to a graph output file.
                for chart in test_name_to_charts[test_name]:
                    graph_name = chart['graph_name']
                    units = chart['units']
                    better_direction = chart['better_direction']
                    url = chart['info_url']
                    chart_keys = chart['keys']

                    store_entry = False
                    for chart_key in chart_keys:
                        actual_keys = [x[0] for x in perf_keys]
                        if any([chart_key_matches_actual_key(chart_key, a)
                                for a in actual_keys]):
                            store_entry = True
                            break

                    if store_entry:
                        output_graph_data_for_entry(
                            test_name, master_name, graph_name, job_name,
                            platform, chrome_ver, units, better_direction, url,
                            perf_keys, chart_keys, options,
                            summary_id_to_rev_num, output_data_dir)

                # Mark this job ID as having been processed.
                with open(os.path.join(output_data_dir,
                                       _COMPLETED_ID_FILE_NAME), 'a') as fp:
                    fp.write(job_id + '\n')
                completed_ids[job_id] = True
                newly_added_count += 1

    return newly_added_count


def initialize_graph_dir(options, input_dir, output_data_dir):
    """Initialize/populate the directory that will serve the perf graphs.

    @param options: An optparse.OptionParser options object.
    @param input_dir: A directory from which to read previously-extracted
        perf data.
    @param output_data_dir: A directory in which to output data files.

    """
    charts = json.loads(open(_CHART_CONFIG_FILE, 'r').read())

    # Identify all the job IDs already processed in the graphs, so that we don't
    # add that data again.
    completed_ids = {}
    completed_id_file = os.path.join(output_data_dir, _COMPLETED_ID_FILE_NAME)
    if os.path.exists(completed_id_file):
        with open(completed_id_file, 'r') as fp:
            job_ids = map(lambda x: x.strip(), fp.readlines())
            for job_id in job_ids:
                completed_ids[job_id] = True

    # Identify the next revision number to use in the graph data files for each
    # test/platform/release combination.
    summary_id_to_rev_num = {}
    rev_num_file = os.path.join(output_data_dir, _REV_NUM_FILE_NAME)
    if os.path.exists(rev_num_file):
        with open(rev_num_file, 'r') as fp:
            summary_id_to_rev_num = json.loads(fp.read())

    # TODO (dennisjeffrey): If we have to add another "test_name_to_X"
    # dictionary to the list below, we should simplify this code to create a
    # single dictionary that maps test names to an object that contains all
    # the X's as attributes.
    test_name_to_charts = {}
    test_names = set()
    test_name_to_old_names = {}
    test_name_to_master_name = {}
    # The _CHART_CONFIG_FILE should (and is assumed to) have one entry per
    # test_name.  That entry should declare all graphs associated with the given
    # test_name.
    for chart in charts:
        test_name_to_charts[chart['test_name']] = chart['graphs']
        test_names.add(chart['test_name'])
        test_name_to_old_names[chart['test_name']] = (
            chart.get('old_test_names', []))
        test_name_to_master_name[chart['test_name']] = (
            chart.get('master', 'CrosMisc'))

    # Scan all database data and format/output only the new data specified in
    # the graph JSON file.
    newly_added_count = 0
    for i, test_name in enumerate(test_names):
        logging.debug('Analyzing/converting data for test %d of %d: %s',
                      i+1, len(test_names), test_name)

        test_data_dir = os.path.join(input_dir, test_name)
        if not os.path.exists(test_data_dir):
            logging.warning('No test data directory for test: %s', test_name)
            continue
        files = os.listdir(test_data_dir)
        for file_name in files:
            logging.debug('Processing perf platform data file: %s', file_name)

            # The current test may be associated with one or more old test
            # names for which perf results exist for the current platform.
            # If so, we need to consider those old perf results too, as being
            # associated with the current test/platform.
            files_to_process = [os.path.join(test_data_dir, file_name)]
            for old_test_name in test_name_to_old_names[test_name]:
                old_test_file_name = os.path.join(input_dir, old_test_name,
                                                  file_name)
                if os.path.exists(old_test_file_name):
                    logging.debug('(also processing this platform for old test '
                                  'name "%s")', old_test_name)
                    files_to_process.append(old_test_file_name)

            newly_added_count += process_perf_data_files(
                files_to_process, test_name,
                test_name_to_master_name.get(test_name), completed_ids,
                test_name_to_charts, options, summary_id_to_rev_num,
                output_data_dir)

    # Store the latest revision numbers for each test/platform/release
    # combination, to be used on the next invocation of this script.
    with open(rev_num_file, 'w') as fp:
        fp.write(json.dumps(summary_id_to_rev_num, indent=2))

    logging.info('Added info for %d new jobs to the graphs!', newly_added_count)


def create_branch_platform_overview(graph_dir, branch, platform,
                                    branch_to_platform_to_test):
    """Create an overview webpage for the given branch/platform combination.

    @param graph_dir: The string directory containing the graphing files.
    @param branch: The string name of the milestone (branch).
    @param platform: The string name of the platform.
    @param branch_to_platform_to_test: A dictionary mapping branch names to
        another dictionary, which maps platform names to a list of test names.

    """
    branches = sorted(branch_to_platform_to_test.keys(), reverse=True)
    platform_to_tests = branch_to_platform_to_test[branch]
    platform_list = sorted(platform_to_tests)
    tests = []
    for test_id in sorted(platform_to_tests[platform]):
        has_data = False
        test_name = ''
        test_dir = os.path.join(graph_dir, 'data', branch, platform, test_id)
        data_file_names = fnmatch.filter(os.listdir(test_dir), '*-summary.dat')
        if len(data_file_names):
            txt_name = data_file_names[0]
            # The name of a test is of the form "X: Y", where X is the
            # autotest name and Y is the graph name.  For example:
            # "platform_BootPerfServer: seconds_from_kernel".
            test_name = (test_id[:test_id.find('__')] + ': ' +
                         txt_name[:txt_name.find('-summary.dat')])
            file_name = os.path.join(test_dir, txt_name)
            has_data = True if os.path.getsize(file_name) > 3 else False
        test_info = {
            'id': test_id,
            'name': test_name,
            'has_data': has_data
        }
        tests.append(test_info)

    # Special check for certain platforms.  Will be removed once we remove
    # all links to the old-style perf graphs.
    # TODO(dennisjeffrey): Simplify the below code once the following bug
    # is addressed to standardize the platform names: crosbug.com/38521.
    platform_converted = 'snow' if platform == 'daisy' else platform
    platform_converted_2 = ('x86-' + platform if platform in
                            ['alex', 'mario', 'zgb'] else platform)

    # Output the overview page.
    page_content = render_to_response(
        os.path.join(_TEMPLATE_DIR, 'branch_platform_overview.html'),
        locals()).content
    file_name = os.path.join(graph_dir, '%s-%s.html' % (branch, platform))
    with open(file_name, 'w') as f:
        f.write(page_content)


def create_comparison_overview(compare_type, graph_dir, test_id, test_dir,
                               branch_to_platform_to_test):
    """Create an overview webpage to compare a test by platform or by branch.

    @param compare_type: The string type of comaprison graph this is, either
        "platform" or "branch".
    @param graph_dir: The string directory containing the graphing files.
    @param test_id: The string unique ID for a test result.
    @param test_dir: The string directory name containing the test data.
    @param branch_to_platform_to_test: A dictionary mapping branch names to
        another dictionary, which maps platform names to a list of test names.

    """
    branches = sorted(branch_to_platform_to_test.keys())
    platforms = [x.keys() for x in branch_to_platform_to_test.values()]
    platforms = sorted(set([x for sublist in platforms for x in sublist]))

    autotest_name = test_id[:test_id.find('__')]

    text_file_names = fnmatch.filter(os.listdir(test_dir), '*-summary.dat')
    test_name = '???'
    if len(text_file_names):
        txt_name = text_file_names[0]
        test_name = txt_name[:txt_name.find('-summary.dat')]

    if compare_type == 'branch':
        outer_list_items = platforms
        inner_list_items = branches
        outer_item_type = 'platform'
    else:
        outer_list_items = reversed(branches)
        inner_list_items = platforms
        outer_item_type = 'branch'

    outer_list = []
    for outer_item in outer_list_items:
        inner_list = []
        for inner_item in inner_list_items:
            if outer_item_type == 'branch':
                branch = outer_item
                platform = inner_item
            else:
                branch = inner_item
                platform = outer_item
            has_data = False
            test_dir = os.path.join(graph_dir, 'data', branch, platform,
                                    test_id)
            if os.path.exists(test_dir):
                data_file_names = fnmatch.filter(os.listdir(test_dir),
                                                 '*-summary.dat')
                if len(data_file_names):
                    file_name = os.path.join(test_dir, data_file_names[0])
                    has_data = True if os.path.getsize(file_name) > 3 else False
            info = {
                'inner_item': inner_item,
                'outer_item': outer_item,
                'branch': branch,
                'platform': platform,
                'has_data': has_data
            }
            inner_list.append(info)
        outer_list.append(inner_list)

    # Output the overview page.
    page_content = render_to_response(
        os.path.join(_TEMPLATE_DIR, 'compare_by_overview.html'),
        locals()).content
    if compare_type == 'branch':
        file_name = os.path.join(graph_dir, test_id + '_branch.html')
    else:
        file_name = os.path.join(graph_dir, test_id + '_platform.html')
    with open(file_name, 'w') as f:
        f.write(page_content)


def generate_overview_pages(graph_dir, options):
    """Create static overview webpages for all the perf graphs.

    @param graph_dir: The string directory containing all the graph data.
    @param options: An optparse.OptionParser options object.

    """
    # Identify all the milestone names for which we want overview pages.
    branches_dir = os.path.join(graph_dir, 'data')
    branches = os.listdir(branches_dir)
    branches = sorted(branches)
    branches = [x for x in branches
                if os.path.isdir(os.path.join(branches_dir, x)) and
                int(x[1:]) >= options.oldest_milestone]

    unique_tests = set()
    unique_test_to_dir = {}
    branch_to_platform_to_test = {}

    for branch in branches:
        platforms_dir = os.path.join(branches_dir, branch)
        if not os.path.isdir(platforms_dir):
            continue
        platforms = os.listdir(platforms_dir)

        platform_to_tests = {}
        for platform in platforms:
            tests_dir = os.path.join(platforms_dir, platform)
            tests = os.listdir(tests_dir)

            for test in tests:
                test_dir = os.path.join(tests_dir, test)
                unique_tests.add(test)
                unique_test_to_dir[test] = test_dir

            platform_to_tests[platform] = tests

        branch_to_platform_to_test[branch] = platform_to_tests

    for branch in branch_to_platform_to_test:
        platforms = branch_to_platform_to_test[branch]
        for platform in platforms:
            # Create overview page for this branch/platform combination.
            create_branch_platform_overview(
                graph_dir, branch, platform, branch_to_platform_to_test)

    # Make index.html a symlink to the most recent branch.
    latest_branch = branches[-1]
    first_plat_for_branch = sorted(
        branch_to_platform_to_test[latest_branch].keys())[0]
    symlink_force(
        os.path.join(graph_dir, 'index.html'),
        '%s-%s.html' % (latest_branch, first_plat_for_branch))

    # Now create overview pages for each test that compare by platform and by
    # branch.
    for test_id in unique_tests:
        for compare_type in ['branch', 'platform']:
            create_comparison_overview(
                compare_type, graph_dir, test_id, unique_test_to_dir[test_id],
                branch_to_platform_to_test)


def cleanup(dir_name):
    """Cleans up when this script is done.

    @param dir_name: A directory containing files to clean up.

    """
    curr_pid_file = os.path.join(dir_name, _CURR_PID_FILE_NAME)
    if os.path.isfile(curr_pid_file):
        os.remove(curr_pid_file)


def main():
    """Main function."""
    parser = optparse.OptionParser()
    parser.add_option('-i', '--input-dir', metavar='DIR', type='string',
                      default=_DATA_DIR,
                      help='Absolute path to the input directory from which to '
                           'read the raw perf data previously extracted from '
                           'the database. Assumed to contain a subfolder named '
                           '"data". Defaults to "%default".')
    parser.add_option('-o', '--output-dir', metavar='DIR', type='string',
                      default=_GRAPH_DIR,
                      help='Absolute path to the output directory in which to '
                           'write data files to be displayed on perf graphs. '
                           'Will be written into a subfolder named "graphs". '
                           'Defaults to "%default".')
    parser.add_option('-t', '--tot-milestone', metavar='MSTONE', type='int',
                      default=_TOT_MILESTONE,
                      help='Tip-of-tree (most recent) milestone number. '
                           'Defaults to milestone %default (R%default).')
    parser.add_option('-l', '--oldest-milestone', metavar='MSTONE', type='int',
                      default=_OLDEST_MILESTONE_TO_GRAPH,
                      help='Oldest milestone number to display in the graphs. '
                           'Defaults to milestone %default (R%default).')
    parser.add_option('-c', '--clean', action='store_true', default=False,
                      help='Clean/delete existing graph files and then '
                           're-create them from scratch.')
    parser.add_option('-v', '--verbose', action='store_true', default=False,
                      help='Use verbose logging.')
    options, _ = parser.parse_args()

    log_level = logging.DEBUG if options.verbose else logging.INFO
    logging.basicConfig(format='%(asctime)s %(levelname)s: %(message)s',
                        level=log_level)

    input_dir = os.path.join(options.input_dir, 'data')
    if not os.path.isdir(input_dir):
        logging.error('Could not find input data directory "%s"', input_dir)
        logging.error('Did you forget to run extract_perf.py first?')
        sys.exit(1)

    common.die_if_already_running(
        os.path.join(input_dir, _CURR_PID_FILE_NAME), logging)

    output_dir = os.path.join(options.output_dir, 'graphs')
    output_data_dir = os.path.join(output_dir, 'data')
    if options.clean:
        remove_path(output_dir)
        os.makedirs(output_data_dir)

    initialize_graph_dir(options, input_dir, output_data_dir)

    ui_dir = os.path.join(output_dir, 'ui')
    if not os.path.exists(ui_dir):
        logging.debug('Copying "ui" directory to %s', ui_dir)
        shutil.copytree(os.path.join(_SCRIPT_DIR, 'ui'), ui_dir)
    doc_dir = os.path.join(output_dir, 'doc')
    if not os.path.exists(doc_dir):
        logging.debug('Copying "doc" directory to %s', doc_dir)
        shutil.copytree(os.path.join(_SCRIPT_DIR, 'doc'), doc_dir)

    generate_overview_pages(output_dir, options)
    set_world_read_permissions(output_dir)

    cleanup(input_dir)
    logging.info('All done!')


if __name__ == '__main__':
    main()
