# Copyright (c) 2013 The Chromium OS Authors.
#
# Bloat-o-meter code used here Copyright 2004 Matt Mackall <mpm@selenic.com>
#
# SPDX-License-Identifier:	GPL-2.0+
#

import collections
from datetime import datetime, timedelta
import glob
import os
import re
import Queue
import shutil
import string
import sys
import time

import builderthread
import command
import gitutil
import terminal
import toolchain


"""
Theory of Operation

Please see README for user documentation, and you should be familiar with
that before trying to make sense of this.

Buildman works by keeping the machine as busy as possible, building different
commits for different boards on multiple CPUs at once.

The source repo (self.git_dir) contains all the commits to be built. Each
thread works on a single board at a time. It checks out the first commit,
configures it for that board, then builds it. Then it checks out the next
commit and builds it (typically without re-configuring). When it runs out
of commits, it gets another job from the builder and starts again with that
board.

Clearly the builder threads could work either way - they could check out a
commit and then built it for all boards. Using separate directories for each
commit/board pair they could leave their build product around afterwards
also.

The intent behind building a single board for multiple commits, is to make
use of incremental builds. Since each commit is built incrementally from
the previous one, builds are faster. Reconfiguring for a different board
removes all intermediate object files.

Many threads can be working at once, but each has its own working directory.
When a thread finishes a build, it puts the output files into a result
directory.

The base directory used by buildman is normally '../<branch>', i.e.
a directory higher than the source repository and named after the branch
being built.

Within the base directory, we have one subdirectory for each commit. Within
that is one subdirectory for each board. Within that is the build output for
that commit/board combination.

Buildman also create working directories for each thread, in a .bm-work/
subdirectory in the base dir.

As an example, say we are building branch 'us-net' for boards 'sandbox' and
'seaboard', and say that us-net has two commits. We will have directories
like this:

us-net/             base directory
    01_of_02_g4ed4ebc_net--Add-tftp-speed-/
        sandbox/
            u-boot.bin
        seaboard/
            u-boot.bin
    02_of_02_g4ed4ebc_net--Check-tftp-comp/
        sandbox/
            u-boot.bin
        seaboard/
            u-boot.bin
    .bm-work/
        00/         working directory for thread 0 (contains source checkout)
            build/  build output
        01/         working directory for thread 1
            build/  build output
        ...
u-boot/             source directory
    .git/           repository
"""

# Possible build outcomes
OUTCOME_OK, OUTCOME_WARNING, OUTCOME_ERROR, OUTCOME_UNKNOWN = range(4)

# Translate a commit subject into a valid filename
trans_valid_chars = string.maketrans("/: ", "---")


class Builder:
    """Class for building U-Boot for a particular commit.

    Public members: (many should ->private)
        active: True if the builder is active and has not been stopped
        already_done: Number of builds already completed
        base_dir: Base directory to use for builder
        checkout: True to check out source, False to skip that step.
            This is used for testing.
        col: terminal.Color() object
        count: Number of commits to build
        do_make: Method to call to invoke Make
        fail: Number of builds that failed due to error
        force_build: Force building even if a build already exists
        force_config_on_failure: If a commit fails for a board, disable
            incremental building for the next commit we build for that
            board, so that we will see all warnings/errors again.
        force_build_failures: If a previously-built build (i.e. built on
            a previous run of buildman) is marked as failed, rebuild it.
        git_dir: Git directory containing source repository
        last_line_len: Length of the last line we printed (used for erasing
            it with new progress information)
        num_jobs: Number of jobs to run at once (passed to make as -j)
        num_threads: Number of builder threads to run
        out_queue: Queue of results to process
        re_make_err: Compiled regular expression for ignore_lines
        queue: Queue of jobs to run
        threads: List of active threads
        toolchains: Toolchains object to use for building
        upto: Current commit number we are building (0.count-1)
        warned: Number of builds that produced at least one warning
        force_reconfig: Reconfigure U-Boot on each comiit. This disables
            incremental building, where buildman reconfigures on the first
            commit for a baord, and then just does an incremental build for
            the following commits. In fact buildman will reconfigure and
            retry for any failing commits, so generally the only effect of
            this option is to slow things down.
        in_tree: Build U-Boot in-tree instead of specifying an output
            directory separate from the source code. This option is really
            only useful for testing in-tree builds.

    Private members:
        _base_board_dict: Last-summarised Dict of boards
        _base_err_lines: Last-summarised list of errors
        _build_period_us: Time taken for a single build (float object).
        _complete_delay: Expected delay until completion (timedelta)
        _next_delay_update: Next time we plan to display a progress update
                (datatime)
        _show_unknown: Show unknown boards (those not built) in summary
        _timestamps: List of timestamps for the completion of the last
            last _timestamp_count builds. Each is a datetime object.
        _timestamp_count: Number of timestamps to keep in our list.
        _working_dir: Base working directory containing all threads
    """
    class Outcome:
        """Records a build outcome for a single make invocation

        Public Members:
            rc: Outcome value (OUTCOME_...)
            err_lines: List of error lines or [] if none
            sizes: Dictionary of image size information, keyed by filename
                - Each value is itself a dictionary containing
                    values for 'text', 'data' and 'bss', being the integer
                    size in bytes of each section.
            func_sizes: Dictionary keyed by filename - e.g. 'u-boot'. Each
                    value is itself a dictionary:
                        key: function name
                        value: Size of function in bytes
        """
        def __init__(self, rc, err_lines, sizes, func_sizes):
            self.rc = rc
            self.err_lines = err_lines
            self.sizes = sizes
            self.func_sizes = func_sizes

    def __init__(self, toolchains, base_dir, git_dir, num_threads, num_jobs,
                 gnu_make='make', checkout=True, show_unknown=True, step=1):
        """Create a new Builder object

        Args:
            toolchains: Toolchains object to use for building
            base_dir: Base directory to use for builder
            git_dir: Git directory containing source repository
            num_threads: Number of builder threads to run
            num_jobs: Number of jobs to run at once (passed to make as -j)
            gnu_make: the command name of GNU Make.
            checkout: True to check out source, False to skip that step.
                This is used for testing.
            show_unknown: Show unknown boards (those not built) in summary
            step: 1 to process every commit, n to process every nth commit
        """
        self.toolchains = toolchains
        self.base_dir = base_dir
        self._working_dir = os.path.join(base_dir, '.bm-work')
        self.threads = []
        self.active = True
        self.do_make = self.Make
        self.gnu_make = gnu_make
        self.checkout = checkout
        self.num_threads = num_threads
        self.num_jobs = num_jobs
        self.already_done = 0
        self.force_build = False
        self.git_dir = git_dir
        self._show_unknown = show_unknown
        self._timestamp_count = 10
        self._build_period_us = None
        self._complete_delay = None
        self._next_delay_update = datetime.now()
        self.force_config_on_failure = True
        self.force_build_failures = False
        self.force_reconfig = False
        self._step = step
        self.in_tree = False
        self._error_lines = 0

        self.col = terminal.Color()

        self.queue = Queue.Queue()
        self.out_queue = Queue.Queue()
        for i in range(self.num_threads):
            t = builderthread.BuilderThread(self, i)
            t.setDaemon(True)
            t.start()
            self.threads.append(t)

        self.last_line_len = 0
        t = builderthread.ResultThread(self)
        t.setDaemon(True)
        t.start()
        self.threads.append(t)

        ignore_lines = ['(make.*Waiting for unfinished)', '(Segmentation fault)']
        self.re_make_err = re.compile('|'.join(ignore_lines))

    def __del__(self):
        """Get rid of all threads created by the builder"""
        for t in self.threads:
            del t

    def SetDisplayOptions(self, show_errors=False, show_sizes=False,
                          show_detail=False, show_bloat=False):
        """Setup display options for the builder.

        show_errors: True to show summarised error/warning info
        show_sizes: Show size deltas
        show_detail: Show detail for each board
        show_bloat: Show detail for each function
        """
        self._show_errors = show_errors
        self._show_sizes = show_sizes
        self._show_detail = show_detail
        self._show_bloat = show_bloat

    def _AddTimestamp(self):
        """Add a new timestamp to the list and record the build period.

        The build period is the length of time taken to perform a single
        build (one board, one commit).
        """
        now = datetime.now()
        self._timestamps.append(now)
        count = len(self._timestamps)
        delta = self._timestamps[-1] - self._timestamps[0]
        seconds = delta.total_seconds()

        # If we have enough data, estimate build period (time taken for a
        # single build) and therefore completion time.
        if count > 1 and self._next_delay_update < now:
            self._next_delay_update = now + timedelta(seconds=2)
            if seconds > 0:
                self._build_period = float(seconds) / count
                todo = self.count - self.upto
                self._complete_delay = timedelta(microseconds=
                        self._build_period * todo * 1000000)
                # Round it
                self._complete_delay -= timedelta(
                        microseconds=self._complete_delay.microseconds)

        if seconds > 60:
            self._timestamps.popleft()
            count -= 1

    def ClearLine(self, length):
        """Clear any characters on the current line

        Make way for a new line of length 'length', by outputting enough
        spaces to clear out the old line. Then remember the new length for
        next time.

        Args:
            length: Length of new line, in characters
        """
        if length < self.last_line_len:
            print ' ' * (self.last_line_len - length),
            print '\r',
        self.last_line_len = length
        sys.stdout.flush()

    def SelectCommit(self, commit, checkout=True):
        """Checkout the selected commit for this build
        """
        self.commit = commit
        if checkout and self.checkout:
            gitutil.Checkout(commit.hash)

    def Make(self, commit, brd, stage, cwd, *args, **kwargs):
        """Run make

        Args:
            commit: Commit object that is being built
            brd: Board object that is being built
            stage: Stage that we are at (distclean, config, build)
            cwd: Directory where make should be run
            args: Arguments to pass to make
            kwargs: Arguments to pass to command.RunPipe()
        """
        cmd = [self.gnu_make] + list(args)
        result = command.RunPipe([cmd], capture=True, capture_stderr=True,
                cwd=cwd, raise_on_error=False, **kwargs)
        return result

    def ProcessResult(self, result):
        """Process the result of a build, showing progress information

        Args:
            result: A CommandResult object, which indicates the result for
                    a single build
        """
        col = terminal.Color()
        if result:
            target = result.brd.target

            if result.return_code < 0:
                self.active = False
                command.StopAll()
                return

            self.upto += 1
            if result.return_code != 0:
                self.fail += 1
            elif result.stderr:
                self.warned += 1
            if result.already_done:
                self.already_done += 1
            if self._verbose:
                print '\r',
                self.ClearLine(0)
                boards_selected = {target : result.brd}
                self.ResetResultSummary(boards_selected)
                self.ProduceResultSummary(result.commit_upto, self.commits,
                                          boards_selected)
        else:
            target = '(starting)'

        # Display separate counts for ok, warned and fail
        ok = self.upto - self.warned - self.fail
        line = '\r' + self.col.Color(self.col.GREEN, '%5d' % ok)
        line += self.col.Color(self.col.YELLOW, '%5d' % self.warned)
        line += self.col.Color(self.col.RED, '%5d' % self.fail)

        name = ' /%-5d  ' % self.count

        # Add our current completion time estimate
        self._AddTimestamp()
        if self._complete_delay:
            name += '%s  : ' % self._complete_delay
        # When building all boards for a commit, we can print a commit
        # progress message.
        if result and result.commit_upto is None:
            name += 'commit %2d/%-3d' % (self.commit_upto + 1,
                    self.commit_count)

        name += target
        print line + name,
        length = 14 + len(name)
        self.ClearLine(length)

    def _GetOutputDir(self, commit_upto):
        """Get the name of the output directory for a commit number

        The output directory is typically .../<branch>/<commit>.

        Args:
            commit_upto: Commit number to use (0..self.count-1)
        """
        if self.commits:
            commit = self.commits[commit_upto]
            subject = commit.subject.translate(trans_valid_chars)
            commit_dir = ('%02d_of_%02d_g%s_%s' % (commit_upto + 1,
                    self.commit_count, commit.hash, subject[:20]))
        else:
            commit_dir = 'current'
        output_dir = os.path.join(self.base_dir, commit_dir)
        return output_dir

    def GetBuildDir(self, commit_upto, target):
        """Get the name of the build directory for a commit number

        The build directory is typically .../<branch>/<commit>/<target>.

        Args:
            commit_upto: Commit number to use (0..self.count-1)
            target: Target name
        """
        output_dir = self._GetOutputDir(commit_upto)
        return os.path.join(output_dir, target)

    def GetDoneFile(self, commit_upto, target):
        """Get the name of the done file for a commit number

        Args:
            commit_upto: Commit number to use (0..self.count-1)
            target: Target name
        """
        return os.path.join(self.GetBuildDir(commit_upto, target), 'done')

    def GetSizesFile(self, commit_upto, target):
        """Get the name of the sizes file for a commit number

        Args:
            commit_upto: Commit number to use (0..self.count-1)
            target: Target name
        """
        return os.path.join(self.GetBuildDir(commit_upto, target), 'sizes')

    def GetFuncSizesFile(self, commit_upto, target, elf_fname):
        """Get the name of the funcsizes file for a commit number and ELF file

        Args:
            commit_upto: Commit number to use (0..self.count-1)
            target: Target name
            elf_fname: Filename of elf image
        """
        return os.path.join(self.GetBuildDir(commit_upto, target),
                            '%s.sizes' % elf_fname.replace('/', '-'))

    def GetObjdumpFile(self, commit_upto, target, elf_fname):
        """Get the name of the objdump file for a commit number and ELF file

        Args:
            commit_upto: Commit number to use (0..self.count-1)
            target: Target name
            elf_fname: Filename of elf image
        """
        return os.path.join(self.GetBuildDir(commit_upto, target),
                            '%s.objdump' % elf_fname.replace('/', '-'))

    def GetErrFile(self, commit_upto, target):
        """Get the name of the err file for a commit number

        Args:
            commit_upto: Commit number to use (0..self.count-1)
            target: Target name
        """
        output_dir = self.GetBuildDir(commit_upto, target)
        return os.path.join(output_dir, 'err')

    def FilterErrors(self, lines):
        """Filter out errors in which we have no interest

        We should probably use map().

        Args:
            lines: List of error lines, each a string
        Returns:
            New list with only interesting lines included
        """
        out_lines = []
        for line in lines:
            if not self.re_make_err.search(line):
                out_lines.append(line)
        return out_lines

    def ReadFuncSizes(self, fname, fd):
        """Read function sizes from the output of 'nm'

        Args:
            fd: File containing data to read
            fname: Filename we are reading from (just for errors)

        Returns:
            Dictionary containing size of each function in bytes, indexed by
            function name.
        """
        sym = {}
        for line in fd.readlines():
            try:
                size, type, name = line[:-1].split()
            except:
                print "Invalid line in file '%s': '%s'" % (fname, line[:-1])
                continue
            if type in 'tTdDbB':
                # function names begin with '.' on 64-bit powerpc
                if '.' in name[1:]:
                    name = 'static.' + name.split('.')[0]
                sym[name] = sym.get(name, 0) + int(size, 16)
        return sym

    def GetBuildOutcome(self, commit_upto, target, read_func_sizes):
        """Work out the outcome of a build.

        Args:
            commit_upto: Commit number to check (0..n-1)
            target: Target board to check
            read_func_sizes: True to read function size information

        Returns:
            Outcome object
        """
        done_file = self.GetDoneFile(commit_upto, target)
        sizes_file = self.GetSizesFile(commit_upto, target)
        sizes = {}
        func_sizes = {}
        if os.path.exists(done_file):
            with open(done_file, 'r') as fd:
                return_code = int(fd.readline())
                err_lines = []
                err_file = self.GetErrFile(commit_upto, target)
                if os.path.exists(err_file):
                    with open(err_file, 'r') as fd:
                        err_lines = self.FilterErrors(fd.readlines())

                # Decide whether the build was ok, failed or created warnings
                if return_code:
                    rc = OUTCOME_ERROR
                elif len(err_lines):
                    rc = OUTCOME_WARNING
                else:
                    rc = OUTCOME_OK

                # Convert size information to our simple format
                if os.path.exists(sizes_file):
                    with open(sizes_file, 'r') as fd:
                        for line in fd.readlines():
                            values = line.split()
                            rodata = 0
                            if len(values) > 6:
                                rodata = int(values[6], 16)
                            size_dict = {
                                'all' : int(values[0]) + int(values[1]) +
                                        int(values[2]),
                                'text' : int(values[0]) - rodata,
                                'data' : int(values[1]),
                                'bss' : int(values[2]),
                                'rodata' : rodata,
                            }
                            sizes[values[5]] = size_dict

            if read_func_sizes:
                pattern = self.GetFuncSizesFile(commit_upto, target, '*')
                for fname in glob.glob(pattern):
                    with open(fname, 'r') as fd:
                        dict_name = os.path.basename(fname).replace('.sizes',
                                                                    '')
                        func_sizes[dict_name] = self.ReadFuncSizes(fname, fd)

            return Builder.Outcome(rc, err_lines, sizes, func_sizes)

        return Builder.Outcome(OUTCOME_UNKNOWN, [], {}, {})

    def GetResultSummary(self, boards_selected, commit_upto, read_func_sizes):
        """Calculate a summary of the results of building a commit.

        Args:
            board_selected: Dict containing boards to summarise
            commit_upto: Commit number to summarize (0..self.count-1)
            read_func_sizes: True to read function size information

        Returns:
            Tuple:
                Dict containing boards which passed building this commit.
                    keyed by board.target
                List containing a summary of error/warning lines
        """
        board_dict = {}
        err_lines_summary = []

        for board in boards_selected.itervalues():
            outcome = self.GetBuildOutcome(commit_upto, board.target,
                                           read_func_sizes)
            board_dict[board.target] = outcome
            for err in outcome.err_lines:
                if err and not err.rstrip() in err_lines_summary:
                    err_lines_summary.append(err.rstrip())
        return board_dict, err_lines_summary

    def AddOutcome(self, board_dict, arch_list, changes, char, color):
        """Add an output to our list of outcomes for each architecture

        This simple function adds failing boards (changes) to the
        relevant architecture string, so we can print the results out
        sorted by architecture.

        Args:
             board_dict: Dict containing all boards
             arch_list: Dict keyed by arch name. Value is a string containing
                    a list of board names which failed for that arch.
             changes: List of boards to add to arch_list
             color: terminal.Colour object
        """
        done_arch = {}
        for target in changes:
            if target in board_dict:
                arch = board_dict[target].arch
            else:
                arch = 'unknown'
            str = self.col.Color(color, ' ' + target)
            if not arch in done_arch:
                str = self.col.Color(color, char) + '  ' + str
                done_arch[arch] = True
            if not arch in arch_list:
                arch_list[arch] = str
            else:
                arch_list[arch] += str


    def ColourNum(self, num):
        color = self.col.RED if num > 0 else self.col.GREEN
        if num == 0:
            return '0'
        return self.col.Color(color, str(num))

    def ResetResultSummary(self, board_selected):
        """Reset the results summary ready for use.

        Set up the base board list to be all those selected, and set the
        error lines to empty.

        Following this, calls to PrintResultSummary() will use this
        information to work out what has changed.

        Args:
            board_selected: Dict containing boards to summarise, keyed by
                board.target
        """
        self._base_board_dict = {}
        for board in board_selected:
            self._base_board_dict[board] = Builder.Outcome(0, [], [], {})
        self._base_err_lines = []

    def PrintFuncSizeDetail(self, fname, old, new):
        grow, shrink, add, remove, up, down = 0, 0, 0, 0, 0, 0
        delta, common = [], {}

        for a in old:
            if a in new:
                common[a] = 1

        for name in old:
            if name not in common:
                remove += 1
                down += old[name]
                delta.append([-old[name], name])

        for name in new:
            if name not in common:
                add += 1
                up += new[name]
                delta.append([new[name], name])

        for name in common:
                diff = new.get(name, 0) - old.get(name, 0)
                if diff > 0:
                    grow, up = grow + 1, up + diff
                elif diff < 0:
                    shrink, down = shrink + 1, down - diff
                delta.append([diff, name])

        delta.sort()
        delta.reverse()

        args = [add, -remove, grow, -shrink, up, -down, up - down]
        if max(args) == 0:
            return
        args = [self.ColourNum(x) for x in args]
        indent = ' ' * 15
        print ('%s%s: add: %s/%s, grow: %s/%s bytes: %s/%s (%s)' %
               tuple([indent, self.col.Color(self.col.YELLOW, fname)] + args))
        print '%s  %-38s %7s %7s %+7s' % (indent, 'function', 'old', 'new',
                                        'delta')
        for diff, name in delta:
            if diff:
                color = self.col.RED if diff > 0 else self.col.GREEN
                msg = '%s  %-38s %7s %7s %+7d' % (indent, name,
                        old.get(name, '-'), new.get(name,'-'), diff)
                print self.col.Color(color, msg)


    def PrintSizeDetail(self, target_list, show_bloat):
        """Show details size information for each board

        Args:
            target_list: List of targets, each a dict containing:
                    'target': Target name
                    'total_diff': Total difference in bytes across all areas
                    <part_name>: Difference for that part
            show_bloat: Show detail for each function
        """
        targets_by_diff = sorted(target_list, reverse=True,
        key=lambda x: x['_total_diff'])
        for result in targets_by_diff:
            printed_target = False
            for name in sorted(result):
                diff = result[name]
                if name.startswith('_'):
                    continue
                if diff != 0:
                    color = self.col.RED if diff > 0 else self.col.GREEN
                msg = ' %s %+d' % (name, diff)
                if not printed_target:
                    print '%10s  %-15s:' % ('', result['_target']),
                    printed_target = True
                print self.col.Color(color, msg),
            if printed_target:
                print
                if show_bloat:
                    target = result['_target']
                    outcome = result['_outcome']
                    base_outcome = self._base_board_dict[target]
                    for fname in outcome.func_sizes:
                        self.PrintFuncSizeDetail(fname,
                                                 base_outcome.func_sizes[fname],
                                                 outcome.func_sizes[fname])


    def PrintSizeSummary(self, board_selected, board_dict, show_detail,
                         show_bloat):
        """Print a summary of image sizes broken down by section.

        The summary takes the form of one line per architecture. The
        line contains deltas for each of the sections (+ means the section
        got bigger, - means smaller). The nunmbers are the average number
        of bytes that a board in this section increased by.

        For example:
           powerpc: (622 boards)   text -0.0
          arm: (285 boards)   text -0.0
          nds32: (3 boards)   text -8.0

        Args:
            board_selected: Dict containing boards to summarise, keyed by
                board.target
            board_dict: Dict containing boards for which we built this
                commit, keyed by board.target. The value is an Outcome object.
            show_detail: Show detail for each board
            show_bloat: Show detail for each function
        """
        arch_list = {}
        arch_count = {}

        # Calculate changes in size for different image parts
        # The previous sizes are in Board.sizes, for each board
        for target in board_dict:
            if target not in board_selected:
                continue
            base_sizes = self._base_board_dict[target].sizes
            outcome = board_dict[target]
            sizes = outcome.sizes

            # Loop through the list of images, creating a dict of size
            # changes for each image/part. We end up with something like
            # {'target' : 'snapper9g45, 'data' : 5, 'u-boot-spl:text' : -4}
            # which means that U-Boot data increased by 5 bytes and SPL
            # text decreased by 4.
            err = {'_target' : target}
            for image in sizes:
                if image in base_sizes:
                    base_image = base_sizes[image]
                    # Loop through the text, data, bss parts
                    for part in sorted(sizes[image]):
                        diff = sizes[image][part] - base_image[part]
                        col = None
                        if diff:
                            if image == 'u-boot':
                                name = part
                            else:
                                name = image + ':' + part
                            err[name] = diff
            arch = board_selected[target].arch
            if not arch in arch_count:
                arch_count[arch] = 1
            else:
                arch_count[arch] += 1
            if not sizes:
                pass    # Only add to our list when we have some stats
            elif not arch in arch_list:
                arch_list[arch] = [err]
            else:
                arch_list[arch].append(err)

        # We now have a list of image size changes sorted by arch
        # Print out a summary of these
        for arch, target_list in arch_list.iteritems():
            # Get total difference for each type
            totals = {}
            for result in target_list:
                total = 0
                for name, diff in result.iteritems():
                    if name.startswith('_'):
                        continue
                    total += diff
                    if name in totals:
                        totals[name] += diff
                    else:
                        totals[name] = diff
                result['_total_diff'] = total
                result['_outcome'] = board_dict[result['_target']]

            count = len(target_list)
            printed_arch = False
            for name in sorted(totals):
                diff = totals[name]
                if diff:
                    # Display the average difference in this name for this
                    # architecture
                    avg_diff = float(diff) / count
                    color = self.col.RED if avg_diff > 0 else self.col.GREEN
                    msg = ' %s %+1.1f' % (name, avg_diff)
                    if not printed_arch:
                        print '%10s: (for %d/%d boards)' % (arch, count,
                                arch_count[arch]),
                        printed_arch = True
                    print self.col.Color(color, msg),

            if printed_arch:
                print
                if show_detail:
                    self.PrintSizeDetail(target_list, show_bloat)


    def PrintResultSummary(self, board_selected, board_dict, err_lines,
                           show_sizes, show_detail, show_bloat):
        """Compare results with the base results and display delta.

        Only boards mentioned in board_selected will be considered. This
        function is intended to be called repeatedly with the results of
        each commit. It therefore shows a 'diff' between what it saw in
        the last call and what it sees now.

        Args:
            board_selected: Dict containing boards to summarise, keyed by
                board.target
            board_dict: Dict containing boards for which we built this
                commit, keyed by board.target. The value is an Outcome object.
            err_lines: A list of errors for this commit, or [] if there is
                none, or we don't want to print errors
            show_sizes: Show image size deltas
            show_detail: Show detail for each board
            show_bloat: Show detail for each function
        """
        better = []     # List of boards fixed since last commit
        worse = []      # List of new broken boards since last commit
        new = []        # List of boards that didn't exist last time
        unknown = []    # List of boards that were not built

        for target in board_dict:
            if target not in board_selected:
                continue

            # If the board was built last time, add its outcome to a list
            if target in self._base_board_dict:
                base_outcome = self._base_board_dict[target].rc
                outcome = board_dict[target]
                if outcome.rc == OUTCOME_UNKNOWN:
                    unknown.append(target)
                elif outcome.rc < base_outcome:
                    better.append(target)
                elif outcome.rc > base_outcome:
                    worse.append(target)
            else:
                new.append(target)

        # Get a list of errors that have appeared, and disappeared
        better_err = []
        worse_err = []
        for line in err_lines:
            if line not in self._base_err_lines:
                worse_err.append('+' + line)
        for line in self._base_err_lines:
            if line not in err_lines:
                better_err.append('-' + line)

        # Display results by arch
        if better or worse or unknown or new or worse_err or better_err:
            arch_list = {}
            self.AddOutcome(board_selected, arch_list, better, '',
                    self.col.GREEN)
            self.AddOutcome(board_selected, arch_list, worse, '+',
                    self.col.RED)
            self.AddOutcome(board_selected, arch_list, new, '*', self.col.BLUE)
            if self._show_unknown:
                self.AddOutcome(board_selected, arch_list, unknown, '?',
                        self.col.MAGENTA)
            for arch, target_list in arch_list.iteritems():
                print '%10s: %s' % (arch, target_list)
                self._error_lines += 1
            if better_err:
                print self.col.Color(self.col.GREEN, '\n'.join(better_err))
                self._error_lines += 1
            if worse_err:
                print self.col.Color(self.col.RED, '\n'.join(worse_err))
                self._error_lines += 1

        if show_sizes:
            self.PrintSizeSummary(board_selected, board_dict, show_detail,
                                  show_bloat)

        # Save our updated information for the next call to this function
        self._base_board_dict = board_dict
        self._base_err_lines = err_lines

        # Get a list of boards that did not get built, if needed
        not_built = []
        for board in board_selected:
            if not board in board_dict:
                not_built.append(board)
        if not_built:
            print "Boards not built (%d): %s" % (len(not_built),
                    ', '.join(not_built))

    def ProduceResultSummary(self, commit_upto, commits, board_selected):
            board_dict, err_lines = self.GetResultSummary(board_selected,
                    commit_upto, read_func_sizes=self._show_bloat)
            if commits:
                msg = '%02d: %s' % (commit_upto + 1,
                        commits[commit_upto].subject)
                print self.col.Color(self.col.BLUE, msg)
            self.PrintResultSummary(board_selected, board_dict,
                    err_lines if self._show_errors else [],
                    self._show_sizes, self._show_detail, self._show_bloat)

    def ShowSummary(self, commits, board_selected):
        """Show a build summary for U-Boot for a given board list.

        Reset the result summary, then repeatedly call GetResultSummary on
        each commit's results, then display the differences we see.

        Args:
            commit: Commit objects to summarise
            board_selected: Dict containing boards to summarise
        """
        self.commit_count = len(commits) if commits else 1
        self.commits = commits
        self.ResetResultSummary(board_selected)
        self._error_lines = 0

        for commit_upto in range(0, self.commit_count, self._step):
            self.ProduceResultSummary(commit_upto, commits, board_selected)
        if not self._error_lines:
            print self.col.Color(self.col.GREEN, '(no errors to report)')


    def SetupBuild(self, board_selected, commits):
        """Set up ready to start a build.

        Args:
            board_selected: Selected boards to build
            commits: Selected commits to build
        """
        # First work out how many commits we will build
        count = (self.commit_count + self._step - 1) / self._step
        self.count = len(board_selected) * count
        self.upto = self.warned = self.fail = 0
        self._timestamps = collections.deque()

    def GetThreadDir(self, thread_num):
        """Get the directory path to the working dir for a thread.

        Args:
            thread_num: Number of thread to check.
        """
        return os.path.join(self._working_dir, '%02d' % thread_num)

    def _PrepareThread(self, thread_num, setup_git):
        """Prepare the working directory for a thread.

        This clones or fetches the repo into the thread's work directory.

        Args:
            thread_num: Thread number (0, 1, ...)
            setup_git: True to set up a git repo clone
        """
        thread_dir = self.GetThreadDir(thread_num)
        builderthread.Mkdir(thread_dir)
        git_dir = os.path.join(thread_dir, '.git')

        # Clone the repo if it doesn't already exist
        # TODO(sjg@chromium): Perhaps some git hackery to symlink instead, so
        # we have a private index but uses the origin repo's contents?
        if setup_git and self.git_dir:
            src_dir = os.path.abspath(self.git_dir)
            if os.path.exists(git_dir):
                gitutil.Fetch(git_dir, thread_dir)
            else:
                print 'Cloning repo for thread %d' % thread_num
                gitutil.Clone(src_dir, thread_dir)

    def _PrepareWorkingSpace(self, max_threads, setup_git):
        """Prepare the working directory for use.

        Set up the git repo for each thread.

        Args:
            max_threads: Maximum number of threads we expect to need.
            setup_git: True to set up a git repo clone
        """
        builderthread.Mkdir(self._working_dir)
        for thread in range(max_threads):
            self._PrepareThread(thread, setup_git)

    def _PrepareOutputSpace(self):
        """Get the output directories ready to receive files.

        We delete any output directories which look like ones we need to
        create. Having left over directories is confusing when the user wants
        to check the output manually.
        """
        dir_list = []
        for commit_upto in range(self.commit_count):
            dir_list.append(self._GetOutputDir(commit_upto))

        for dirname in glob.glob(os.path.join(self.base_dir, '*')):
            if dirname not in dir_list:
                shutil.rmtree(dirname)

    def BuildBoards(self, commits, board_selected, keep_outputs, verbose):
        """Build all commits for a list of boards

        Args:
            commits: List of commits to be build, each a Commit object
            boards_selected: Dict of selected boards, key is target name,
                    value is Board object
            keep_outputs: True to save build output files
            verbose: Display build results as they are completed
        """
        self.commit_count = len(commits) if commits else 1
        self.commits = commits
        self._verbose = verbose

        self.ResetResultSummary(board_selected)
        builderthread.Mkdir(self.base_dir)
        self._PrepareWorkingSpace(min(self.num_threads, len(board_selected)),
                commits is not None)
        self._PrepareOutputSpace()
        self.SetupBuild(board_selected, commits)
        self.ProcessResult(None)

        # Create jobs to build all commits for each board
        for brd in board_selected.itervalues():
            job = builderthread.BuilderJob()
            job.board = brd
            job.commits = commits
            job.keep_outputs = keep_outputs
            job.step = self._step
            self.queue.put(job)

        # Wait until all jobs are started
        self.queue.join()

        # Wait until we have processed all output
        self.out_queue.join()
        print
        self.ClearLine(0)
