#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Create a new variant of an existing base board

This program will call all of the scripts that create the various pieces
of a new variant. For example to create a new variant of the hatch base
board, the following scripts are called:

* third_party/coreboot/util/mainboard/google/hatch/create_coreboot_variant.sh
* platform/dev/contrib/variant/create_coreboot_config.sh
* private-overlays/baseboard-hatch-private/sys-boot/
 * coreboot-private-files-hatch/files/add_fitimage.sh
 * coreboot-private-files-hatch/asset_generation/gen_fit_image.sh
  * Outside the chroot, because it uses WINE to run the FIT tools
* platform/dev/contrib/variant/create_initial_ec_image.sh
* platform/dev/contrib/variant/add_variant_to_yaml.sh
* private-overlays/overlay-hatch-private/chromeos-base/
 * chromeos-config-bsp-hatch-private/add_variant.sh

Once the scripts are done, the following repos have changes

* third_party/coreboot
* third_party/chromiumos-overlay
* private-overlays/baseboard-hatch-private
* platform/ec
* private-overlays/overlay-hatch-private
* overlays

Copyright 2019 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.
"""

from __future__ import print_function
import argparse
import logging
import os
import re
import shutil
import subprocess
import sys
import variant_status


def main():
    """Create a new variant of an existing base board

    This program automates the creation of a new variant of an existing
    base board by calling various scripts that clone the base board, modify
    files for the new variant, stage commits, and upload to gerrit.

    Note that one of the following is required:
    * --continue
    * --board=BOARD --variant=VARIANT [--bug=BUG]
    """
    board, variant, bug, continue_flag = get_args()

    if not check_flags(board, variant, bug, continue_flag):
        return False

    status = get_status(board, variant, bug, continue_flag)
    if status is None:
        return False

    status.load()

    while status.stage is not None:
        status.save()
        if not perform_stage(status):
            logging.debug('perform_stage returned False; exiting ...')
            return False

        move_to_next_stage(status)

    return True


def get_args():
    """Parse the command-line arguments

    There doesn't appear to be a way to specify that --continue is
    mutually exclusive with --board, --variant, and --bug. As a result,
    all arguments are optional, and another function will apply the logic
    to check if there is an illegal combination of arguments.

    Returns a list of:
        board             Name of the base board
        variant           Name of the variant being created
        bug               Text for bug number, if any ('None' otherwise)
        continue_flag     Flag if --continue was specified
    """
    parser = argparse.ArgumentParser(
        description=main.__doc__,
        formatter_class=argparse.RawTextHelpFormatter)
    parser.add_argument('--board', type=str, help='Name of the base board')
    parser.add_argument(
        '--variant', type=str, help='Name of the new variant to create')
    parser.add_argument(
        '--bug', type=str, help='Bug number to reference in commits')
    parser.add_argument(
        '--continue', action='store_true',
        dest='continue_flag', help='Continue the process from where it paused')
    parser.add_argument(
        '--verbose', action='store_true',
        dest='verbose_flag', help='Enable verbose output of progress')
    args = parser.parse_args()

    if args.verbose_flag:
        logging.basicConfig(level=logging.DEBUG)
    else:
        logging.basicConfig(level=logging.INFO)

    board = args.board
    if board is not None:
        board = board.lower()

    variant = args.variant
    if variant is not None:
        variant = variant.lower()

    bug = args.bug or 'None'

    return (board, variant, bug, args.continue_flag)


def check_flags(board, variant, bug, continue_flag):
    """Check the flags to ensure no invalid combinations

    We allow any of the following:
    --continue
    --board=board_name --variant=variant_name
    --board=board_name --variant=variant_name --bug=bug_text

    The argument parser does have the functionality to represent the
    combination of --board and --variant as a single mutually-exclusive
    argument, so we have to use this function to do the checking.

    Params:
        board             Name of the base board
        variant           Name of the variant being created
        bug               Text for bug number, if any ('None' otherwise)
        continue_flag     Flag if --continue was specified

    Returns:
        True if the arguments are acceptable, False otherwise
    """
    if continue_flag:
        if board is not None or variant is not None:
            logging.error('--continue cannot have other options')
            return False

        if bug != 'None':
            logging.error('--continue cannot have other options')
            return False
    else:
        if board is None:
            logging.error('--board must be specified')
            return False

        if variant is None:
            logging.error('--variant must be specified')
            return False

    return True


def file_exists(filepath, filename):
    """Determine if a path and file exists

    Params:
        filepath      Path where build outputs should be found, e.g.
                      /build/hatch/firmware
        filename      File that should exist in that path, e.g.
                      image-sushi.bin

    Returns:
        True if file exists in that path, False otherwise
    """
    fullname = os.path.join(filepath, filename)
    return os.path.exists(fullname) and os.path.isfile(fullname)


def get_status(board, variant, bug, continue_flag):
    """Create the status file or get the previous status

    This program can stop at several places as we have to wait for CLs
    to work through CQ or be upstreamed into the chromiumos tree, so just
    like a git cherry-pick, there is a --continue option to pick up where
    you left off.

    If the --continue flag is present, make sure that the status file
    exists, and fail if it doesn't.

    If the --continue flag is not present, then create the status file
    with the board, variant, and bug details. If the status file already
    exists, this is an error case.

    The function returns an object with several fields:
    * board - the name of the baseboard, e.g. 'hatch'
    * variant - the name of the variant, e.g. 'sushi'
    * bug - optional text for a bug ID, used in the git commit messages.
        Could be 'None' (as text, not the python None), or something like
        'b:12345' for buganizer, or 'chromium:12345'
    * workon - list of packages that will need `cros_workon start` before
        we can `emerge`. Each function can add package names to this list.
    * emerge - list of packages that we need to `emerge` at the end. Each
        functions can add package names to this list.
    * stage - internal state tracking, what stage of the variant creation
        we are at.
    * yaml_file - internal, just the name of the file where all this data
        gets saved.

    These data might come from the status file (because we read it), or
    they might be the initial values after we created the file (because
    it did not already exist).

    Params:
        board             Name of the base board
        variant           Name of the variant being created
        bug               Text for bug number, if any ('None' otherwise)
        continue_flag     Flag if --continue was specified

    Returns:
        variant_status object that points to the yaml file
    """
    status = variant_status.variant_status()
    if continue_flag:
        if not status.yaml_file_exists():
            logging.error(
                'new_variant is not in progress; nothing to --continue')
            return None
    else:
        if status.yaml_file_exists():
            logging.error(
                'new_variant already in progress; did you forget --continue?')
            return None

        status.board = board
        status.variant = variant
        status.bug = bug
        status.stage = 'cb_variant'
        status.save()

    return status


# Constants for the stages, so we don't have to worry about misspelling them
# pylint: disable=bad-whitespace
# Allow extra spaces around = so that we can line things up nicely
CB_VARIANT    = 'cb_variant'
CB_CONFIG     = 'cb_config'
ADD_FIT       = 'add_fit'
GEN_FIT       = 'gen_fit'
COMMIT_FIT    = 'commit_fit'
EC_IMAGE      = 'ec_image'
EC_BUILDALL   = 'ec_buildall'
ADD_YAML      = 'add_yaml'
BUILD_YAML    = 'build_yaml'
EMERGE        = 'emerge'
PUSH          = 'push'
UPLOAD        = 'upload'
FIND          = 'find'
CQ_DEPEND     = 'cq_depend'
CLEAN_UP      = 'clean_up'
# pylint: enable=bad-whitespace


def perform_stage(status):
    """Call the appropriate function for the current stage

    Params:
        st  dictionary that provides details including
            the board name, variant name, and bug ID

    Returns:
        True if the stage succeeded, False if it failed
    """
    # Function to call based on the stage
    dispatch = {
        CB_VARIANT:     create_coreboot_variant,
        CB_CONFIG:      create_coreboot_config,
        ADD_FIT:        add_fitimage,
        GEN_FIT:        gen_fit_image_outside_chroot,
        COMMIT_FIT:     commit_fitimage,
        EC_IMAGE:       create_initial_ec_image,
        EC_BUILDALL:    ec_buildall,
        ADD_YAML:       add_variant_to_yaml,
        BUILD_YAML:     build_yaml,
        EMERGE:         emerge_all,
        PUSH:           push_coreboot,
        UPLOAD:         upload_CLs,
        FIND:           find_coreboot_upstream,
        CQ_DEPEND:      add_cq_depends,
        CLEAN_UP:       clean_up,
    }

    if status.stage not in dispatch:
        logging.error('Unknown stage "%s", aborting...', status.stage)
        sys.exit(1)

    return dispatch[status.stage](status)


def move_to_next_stage(status):
    """Move to the next state

    Params:
        status      variant_status object tracking our board, variant, etc.
    """

    # Stage to move to if the current one is successful
    # TODO(pfagerburg) instead of using a map, have a list of stages that
    # is saved to the yaml file. Create logic to populate that list at
    # the beginning of the process, based on the --board argument; hatch
    # can have a different list of stages compared to e.g. volteer.
    next_stage = {
        CB_VARIANT:     CB_CONFIG,
        CB_CONFIG:      ADD_FIT,
        ADD_FIT:        GEN_FIT,
        GEN_FIT:        COMMIT_FIT,
        COMMIT_FIT:     EC_IMAGE,
        EC_IMAGE:       EC_BUILDALL,
        EC_BUILDALL:    ADD_YAML,
        ADD_YAML:       BUILD_YAML,
        BUILD_YAML:     EMERGE,
        EMERGE:         PUSH,
        PUSH:           UPLOAD,
        UPLOAD:         FIND,
        FIND:           CQ_DEPEND,
        CQ_DEPEND:      CLEAN_UP,
        CLEAN_UP:       None
    }

    if status.stage not in next_stage:
        logging.error('Unknown stage "%s", aborting...', status.stage)
        sys.exit(1)

    status.stage = next_stage[status.stage]


def run_process(args, *, cwd=None, env=None):
    """Wrapper for subprocess.run that will produce debug-level messages

    Params:
        LImited subset, same as for subprocess.run

    Returns:
        Return value from subprocess.run
    """
    logging.debug('Run %s', str(args))
    retval = subprocess.run(args, cwd=cwd, env=env).returncode
    logging.debug('process returns %s', str(retval))
    return retval


def cros_workon(status, action):
    """Call cros_workon for all the 9999 ebuilds we'll be touching

    TODO(pfagerburg) detect 9999 ebuild to know if we have to workon the package

    Params:
        status      variant_status object tracking our board, variant, etc.
        action      'start' or 'stop'

    Returns:
        True if the call to cros_workon was successful, False if failed
    """

    # Build up the command from all the packages in the list
    workon_cmd = ['cros_workon', '--board=' + status.board, action] + status.workon
    return run_process(workon_cmd) == 0


def create_coreboot_variant(status):
    """Create source files for a new variant of the base board in coreboot

    This function calls create_coreboot_variant.sh to set up a new variant
    of the base board.

    Params:
        status      variant_status object tracking our board, variant, etc.

    Returns:
        True if everything succeeded, False if something failed
    """
    logging.info('Running stage create_coreboot_variant')
    status.workon += ['coreboot', 'libpayload', 'vboot_reference',
        'depthcharge']
    # Despite doing the workon here, we don't add this to emerge, because
    # without the configuration (create_coreboot_config), `emerge coreboot`
    # won't build the new variant.
    status.emerge += ['libpayload', 'vboot_reference', 'depthcharge',
        'chromeos-bootimage']

    create_coreboot_variant_sh = os.path.join(
        os.path.expanduser('~/trunk/src/third_party/coreboot'),
        'util/mainboard/google/', status.board, 'create_coreboot_variant.sh')
    return run_process(
        [create_coreboot_variant_sh,
        status.variant,
        status.bug]) == 0


def create_coreboot_config(status):
    """Create a coreboot configuration for a new variant

    This function calls create_coreboot_config.sh, which will make a copy
    of coreboot.${BOARD} into coreboot.${VARIANT}.

    Params:
        status      variant_status object tracking our board, variant, etc.

    Returns:
        True if the script and test build succeeded, False if something failed
    """
    logging.info('Running stage create_coreboot_config')
    status.emerge += ['coreboot']
    create_coreboot_config_sh = os.path.expanduser(
        '~/trunk/src/platform/dev/contrib/variant/create_coreboot_config.sh')
    return run_process(
        [create_coreboot_config_sh,
        status.board,
        status.variant,
        status.bug]) == 0


def add_fitimage(status):
    """Add the source files for a fitimage for the new variant

    This function calls add_fitimage.sh to create a new XSL file for the
    variant's fitimage, which can override settings from the base board's XSL.
    When this is done, the user will have to build the fitimage by running
    gen_fit_image.sh outside of the chroot (and outside of this program's
    control) because gen_fit_image.sh uses WINE, which is not installed in
    the chroot. (There is a linux version of FIT, but it requires Open GL,
    which is also not installed in the chroot.)

    Params:
        status      variant_status object tracking our board, variant, etc.

    Returns:
        True if the script succeeded, False otherwise
    """
    logging.info('Running stage add_fitimage')
    status.workon += ['intel-cmlfsp']
    status.emerge += ['intel-cmlfsp']
    add_fitimage_sh = os.path.expanduser(os.path.join(
        '~/trunk/src/private-overlays',
        'baseboard-' + status.board + '-private',
        'sys-boot',
        'coreboot-private-files-' + status.board,
        'files/add_fitimage.sh'))
    return run_process(
        [add_fitimage_sh,
        status.variant,
        status.bug]) == 0


def gen_fit_image_outside_chroot(status):
    """Tell the user to run gen_fit_image.sh outside the chroot

    As noted for add_Fitimage(), gen_fit_image.sh cannot run inside the
    chroot. This function tells the user to run gen_fit_image.sh in
    their normal environment, and then come back (--continue) when that
    is done.

    Params:
        status      variant_status object tracking our board, variant, etc.

    Returns:
        True
    """
    logging.info('Running stage gen_fit_image_outside_chroot')
    fit_image_files = check_fit_image_files(status)
    # If the list is empty, then `not` of the list is True, so the files
    # we need are all present and we can continue.
    if not fit_image_files:
        return True

    logging.info('The following files need to be generated:')
    for filename in fit_image_files:
        logging.info('* %s', filename)
    logging.info('The fitimage sources are ready for gen_fit_image.sh to process.')
    logging.info('gen_fit_image.sh cannot run inside the chroot. Please open a new terminal')
    logging.info('window, change to the directory where gen_fit_image.sh is located, and run')
    logging.info('./gen_fit_image.sh %s [location of FIT] -b', status.variant)
    logging.info('Then re-start this program with --continue.')
    logging.info('If your chroot is based in ~/chromiumos, then the folder you want is')
    logging.info('~/chromiumos/src/private-overlays/baseboard-%s-private/sys-boot'
        '/coreboot-private-files-%s/asset_generation', status.board, status.board)
    return False


def check_fit_image_files(status):
    """Check if the fitimage has been generated

    This function is not called directly as a stage, and so it doesn't need
    to produce any error messages to the user (except with --verbose).
    gen_fit_image_outside_chroot will call this function to see if the
    fitimage files exist, and if not, then that function will print the
    message about how the user needs to run gen_fit_image.sh outside the
    chroot.

    Params:
        status      variant_status object tracking our board, variant, etc.

    Returns:
        List of files that *DO NOT* exist and need to be created, [] if
        all files are present.
    """
    fitimage_dir = os.path.expanduser(os.path.join(
        '~/trunk/src/private-overlays',
        'baseboard-' + status.board + '-private',
        'sys-boot',
        'coreboot-private-files-' + status.board,
        'asset_generation/outputs'))
    logging.debug('fitimage_dir = "%s"', fitimage_dir)

    files = []
    if not file_exists(fitimage_dir, 'fitimage-' + status.variant + '.bin'):
        files.append('fitimage-' + status.variant + '.bin')

    if not file_exists(fitimage_dir,
                       'fitimage-' + status.variant + '-versions.txt'):
        files.append('fitimage-' + status.variant + '-versions.txt')

    if not file_exists(fitimage_dir, 'fit.log'):
        files.append('fit.log')

    return files


def move_fitimage_file(fitimage_dir, filename):
    """Move fitimage files from create-place to commit-place

    commit_fitimage needs to move the fitimage files from the place where
    they were created to a different directory in the tree. This utility
    function handles joining paths and calling a file move function.

    Params:
        fitimage_dir    Directory where the fitimage files are
        filename        Name of the file being moved

    Returns:
        True if the move succeeded, False if it failed
    """
    src_dir = os.path.join(fitimage_dir, 'asset_generation/outputs')
    src = os.path.join(src_dir, filename)
    dest_dir = os.path.join(fitimage_dir, 'files')
    dest = os.path.join(dest_dir, filename)
    # If src does not exist and dest does, the move is already done => success!
    if not file_exists(src_dir, filename) and file_exists(dest_dir, filename):
        logging.debug('move "%s", "%s" unnecessary because dest exists and'
            ' src does not exist', src, dest)
        return True

    logging.debug('move "%s", "%s"', src, dest)
    return shutil.move(src, dest)


def commit_fitimage(status):
    """Move the fitimage files and add them to a git commit

    This function moves the fitimage binary and -versions files from
    asset_generation/outputs to files/ and then adds those files and
    fit.log to the existing git commit.

    Params:
        status      variant_status object tracking our board, variant, etc.

    Returns:
        True if the copy, git add, and git commit --amend all succeeded.
        False if something failed.
    """
    logging.info('Running stage commit_fitimage')
    fitimage_dir = os.path.expanduser(os.path.join(
        '~/trunk/src/private-overlays',
        'baseboard-' + status.board + '-private',
        'sys-boot',
        'coreboot-private-files-' + status.board))
    logging.debug('fitimage_dir  = "%s"', fitimage_dir)

    # The copy operation will check that the source file exists, so no
    # need to check separately.
    if not move_fitimage_file(fitimage_dir,
                              'fitimage-' + status.variant + '.bin'):
        logging.error('Moving fitimage binary failed')
        return False

    if not move_fitimage_file(fitimage_dir,
                              'fitimage-' + status.variant + '-versions.txt'):
        logging.error('Moving fitimage versions.txt failed')
        return False

    if run_process(
        ['git', 'add',
        'asset_generation/outputs/fit.log',
        'files/fitimage-' + status.variant + '.bin',
        'files/fitimage-' + status.variant + '-versions.txt'
        ],
        cwd=fitimage_dir) != 0:
        return False

    return run_process(['git', 'commit', '--amend', '--no-edit'],
        cwd=fitimage_dir) == 0


def create_initial_ec_image(status):
    """Create an EC image for the variant as a clone of the base board

    This function calls create_initial_ec_image.sh, which will clone the
    base board to create the variant. The shell script will build the
    EC code for the variant, but the repo upload hook insists that we
    have done a `make buildall` before it will allow an upload, so this
    function does the buildall.

    Params:
        status      variant_status object tracking our board, variant, etc.

    Returns:
        True if the script and test build succeeded, False if something failed
    """
    logging.info('Running stage create_initial_ec_image')
    status.workon += ['chromeos-ec']
    status.emerge += ['chromeos-ec']
    create_initial_ec_image_sh = os.path.expanduser(
        '~/trunk/src/platform/dev/contrib/variant/create_initial_ec_image.sh')
    if run_process(
        [create_initial_ec_image_sh,
        status.board,
        status.variant,
        status.bug]) != 0:
        return False

    # create_initial_ec_image.sh will build the ec.bin for this variant
    # if successful.
    ec = os.path.expanduser('~/trunk/src/platform/ec')
    logging.debug('ec = "%s"', ec)
    ec_bin = 'build/' + status.variant + '/ec.bin'
    logging.debug('ec.bin = "%s"', ec_bin)

    return file_exists(ec, ec_bin)


def ec_buildall(status):
    """Do a make buildall -j for the EC, which is required for repo upload

    The upload hook checks to ensure that the entire EC codebase builds
    without error, so we have to run make buildall -j before uploading.

    Params:
        status      variant_status object tracking our board, variant, etc.

    Returns:
        True if the script and test build succeeded, False if something failed
    """
    logging.info('Running stage ec_buildall')
    del status  # unused parameter
    ec = os.path.expanduser('~/trunk/src/platform/ec')
    logging.debug('ec = "%s"', ec)
    return run_process(['make', 'buildall', '-j'], cwd=ec) == 0


def add_variant_to_yaml(status):
    """Add the new variant to the public and private model.yaml files

    This function calls add_variant_to_yaml.sh (the public yaml) and
    add_variant.sh (the private yaml) to add the new variant to
    the yaml files.

    Params:
        st  dictionary that provides details including
            the board name, variant name, and bug ID

    Returns:
        True if the scripts and build succeeded, False is something failed
    """
    logging.info('Running stage add_variant_to_yaml')
    status.workon += ['chromeos-config-bsp-hatch-private']
    status.emerge += ['chromeos-config', 'chromeos-config-bsp',
        'chromeos-config-bsp-hatch', 'chromeos-config-bsp-hatch-private',
        'coreboot-private-files', 'coreboot-private-files-hatch']
    add_variant_to_yaml_sh = os.path.expanduser(
        '~/trunk/src/platform/dev/contrib/variant/add_variant_to_yaml.sh')
    if run_process(
        [add_variant_to_yaml_sh,
        status.board,
        status.variant,
        status.bug
        ]) != 0:
        return False

    add_variant_sh = os.path.expanduser(os.path.join(
        '~/trunk/src/private-overlays',
        'overlay-' + status.board + '-private',
        'chromeos-base',
        'chromeos-config-bsp-' + status.board + '-private',
        'add_variant.sh'))
    if run_process(
        [add_variant_sh,
        status.variant,
        status.bug
        ]) != 0:
        return False

    return True


def build_yaml(status):
    """Build config files from the yaml files

    This function builds the yaml files into the JSON and C code that
    mosys and other tools use, then verifies that the new variant's name
    shows up in all of the output files.

    Params:
        status      variant_status object tracking our board, variant, etc.

    Returns:
        True if the scripts and build succeeded, False is something failed
    """
    logging.info('Running stage build_yaml')
    if run_process(
        ['emerge-' + status.board,
        'chromeos-config-bsp-' + status.board,
        'chromeos-config-bsp-' + status.board + '-private',
        'chromeos-config-bsp',
        'chromeos-config']) != 0:
        return False

    # Check generated files for occurences of the variant name.
    # Each file should have at least one occurence, so use `grep -c` to
    # count the occurrences of the variant name in each file.
    # The results will be something like this:
    #   config.json:10
    #   yaml/config.c:6
    #   yaml/config.yaml:27
    #   yaml/model.yaml:6
    #   yaml/private-model.yaml:10
    # If the variant name doesn't show up in the file, then the count
    # will be 0, so we would see, e.g.
    #   config.json:0
    # We gather the output from grep, decode as UTF-8, split along newlines,
    # and then look for any of the strings ending in :0. If none of them
    # match, then we're good, but if even one of them ends with :0 then
    # there was a problem with generating the files from the yaml.
    chromeos_config = '/build/' + status.board + '/usr/share/chromeos-config'
    logging.debug('chromeos_config = "%s"', chromeos_config)
    # Can't use run because we need to capture the output instead
    # of a status code.
    grep = subprocess.check_output(
        ['grep',
        '-c',
        status.variant,
        'config.json',
        'yaml/config.c',
        'yaml/config.yaml',
        'yaml/model.yaml',
        'yaml/private-model.yaml'], cwd=chromeos_config)
    # Convert from byte string to ASCII
    grep = grep.decode('utf-8')
    # Split into array of individual lines
    grep = grep.split('\n')
    return not bool([s for s in grep if re.search(r':0$', s)])


def emerge_all(status):
    """Build the coreboot BIOS and EC code for the new variant

    Params:
        status      variant_status object tracking our board, variant, etc.

    Returns:
        True if the build succeeded, False if something failed
    """
    logging.info('Running stage emerge_all')
    cros_workon(status, 'start')
    environ = os.environ.copy()
    environ['FW_NAME'] = status.variant
    # Build up the command for emerge from all the packages in the list
    emerge_cmd_and_params = ['emerge-' + status.board] + status.emerge
    if run_process(emerge_cmd_and_params, env=environ) != 0:
        return False

    cros_workon(status, 'stop')
    build_path = '/build/' + status.board + '/firmware'
    logging.debug('build_path = "%s"', build_path)
    if not file_exists(build_path, 'image-' + status.variant + '.bin'):
        logging.error('emerge failed because image-%s.bin does not exist',
            status.variant)
        return False

    if not file_exists(build_path, 'image-' + status.variant + '.dev.bin'):
        logging.error('emerge failed because image-%s.dev.bin does not exist',
            status.variant)
        return False

    if not file_exists(build_path, 'image-' + status.variant + '.net.bin'):
        logging.error('emerge failed because image-%s.net.bin does not exist',
            status.variant)
        return False

    if not file_exists(build_path, 'image-' + status.variant + '.serial.bin'):
        logging.error('emerge failed because image-%s.serial.bin does not exist',
            status.variant)
        return False

    return True


def push_coreboot(status):
    """Push the coreboot CL to coreboot.org

    Params:
        status      variant_status object tracking our board, variant, etc.

    Returns:
        True if the build succeeded, False if something failed
    """
    logging.info('Running stage push_coreboot')
    del status  # unused parameter
    logging.error('TODO (pfagerburg): implement push_coreboot')
    return True


def upload_CLs(status):
    """Upload all CLs to chromiumos

    Params:
        status      variant_status object tracking our board, variant, etc.

    Returns:
        True if the build succeeded, False if something failed
    """
    logging.info('Running stage upload_CLs')
    del status  # unused parameter
    logging.error('TODO (pfagerburg): implement upload_CLs')
    return True


def find_coreboot_upstream(status):
    """Find the coreboot CL after it has been upstreamed to chromiumos

    Params:
        status      variant_status object tracking our board, variant, etc.

    Returns:
        True if the build succeeded, False if something failed
    """
    logging.info('Running stage find_coreboot_upstream')
    del status  # unused parameter
    logging.error('TODO (pfagerburg): implement find_coreboot_upstream')
    return True


def add_cq_depends(status):
    """Add Cq-Depends to all of the CLs in chromiumos

    The CL in coreboot needs to be pushed to coreboot.org, get merged,
    and then get upstreamed into the chromiumos tree before the other
    CLs can cq-depend on it and pass CQ.

    Params:
        status      variant_status object tracking our board, variant, etc.

    Returns:
        True if the build succeeded, False if something failed
    """
    logging.info('Running stage add_cq_depends')
    del status  # unused parameter
    logging.error('TODO (pfagerburg): implement add_cq_depends')
    return True


def clean_up(status):
    """Final clean-up, including delete the status file

    Params:
        status      variant_status object tracking our board, variant, etc.

    Returns:
        True
    """
    logging.info('Running stage clean_up')
    status.rm()
    return True


if __name__ == '__main__':
    sys.exit(not int(main()))
