# Copyright 2012 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""A library to generate and store the manifests for cros builders to use."""

import datetime
import fnmatch
import glob
import logging
import os
import shutil
import tempfile
from xml.dom import minidom

from chromite.cbuildbot import build_status
from chromite.lib import buildbucket_v2
from chromite.lib import builder_status_lib
from chromite.lib import chromeos_version
from chromite.lib import config_lib
from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import git
from chromite.lib import osutils
from chromite.lib import retry_util
from chromite.lib import timeout_util


PUSH_BRANCH = "temp_auto_checkin_branch"
NUM_RETRIES = 20

MANIFEST_ELEMENT = "manifest"
DEFAULT_ELEMENT = "default"
PROJECT_ELEMENT = "project"
REMOTE_ELEMENT = "remote"
PROJECT_NAME_ATTR = "name"
PROJECT_REMOTE_ATTR = "remote"
PROJECT_GROUP_ATTR = "groups"
REMOTE_NAME_ATTR = "name"

PALADIN_COMMIT_ELEMENT = "pending_commit"
PALADIN_PROJECT_ATTR = "project"


class FilterManifestException(Exception):
    """Exception thrown when failing to filter the internal manifest."""


class StatusUpdateException(Exception):
    """Exception gets thrown for failure to update the status."""


class GenerateBuildSpecException(Exception):
    """Exception gets thrown for failure to Generate a buildspec for build."""


class BuildSpecsValueError(Exception):
    """Exception gets thrown when a encountering invalid values."""


def ResolveBuildspec(manifest_dir, buildspec):
    """Look up a buildspec, and return an absolute path to it's manifest.

    A buildspec is a relative path to a pinned manifest in an instance of
    manifest-versions. The trailing '.xml' is optional.

    Formal versions are defined with paths of the form:
      buildspecs/65/10294.0.0.xml

    Other buildsspecs tend to have forms like:
      full/buildspecs/71/11040.0.0-rc3.xml
      paladin/buildspecs/26/3560.0.0-rc5.xml

    Args:
        manifest_dir: Path to a manifest-versions instance (internal or
            external).
        buildspec: buildspec defining which manifest to use.

    Returns:
        Absolute path to pinned manifest file matching the buildspec.

    Raises:
        BuildSpecsValueError if no pinned manifest matches.
    """
    candidate = os.path.join(manifest_dir, buildspec)
    if not candidate.endswith(".xml"):
        candidate += ".xml"

    if not os.path.exists(candidate):
        raise BuildSpecsValueError("buildspec %s does not exist." % buildspec)

    return candidate


def ResolveBuildspecVersion(manifest_dir, version):
    """Resolve a version '1.2.3' to the pinned manifest matching it.

    Args:
        manifest_dir: Path to a manifest-versions instance (internal or
            external).
        version: ChromeOS version number, of the form 11040.0.0.

    Returns:
        Absolute path to pinned manifest file matching the version number.

    Raises:
        BuildSpecsValueError if no pinned manifest matches.
    """
    chrome_branches = os.listdir(os.path.join(manifest_dir, "buildspecs"))

    for cb in chrome_branches:
        candidate = os.path.join(
            manifest_dir, "buildspecs", cb, "%s.xml" % version
        )

        if os.path.exists(candidate):
            return candidate

    raise BuildSpecsValueError("No buildspec for version %s found." % version)


def RefreshManifestCheckout(manifest_dir, manifest_repo):
    """Checks out manifest-versions into the manifest directory.

    If a repository is already present, it will be cleansed of any local
    changes and restored to its pristine state, checking out the origin.
    """
    logging.info("Refreshing %s from %s", manifest_dir, manifest_repo)

    reinitialize = True
    if os.path.exists(manifest_dir):
        result = git.RunGit(
            manifest_dir, ["config", "remote.origin.url"], check=False
        )
        if result.returncode == 0 and result.stdout.rstrip() == manifest_repo:
            logging.info("Updating manifest-versions checkout.")
            try:
                git.RunGit(manifest_dir, ["gc", "--auto"])
                git.CleanAndCheckoutUpstream(manifest_dir)
            except cros_build_lib.RunCommandError:
                logging.warning("Could not update manifest-versions checkout.")
            else:
                reinitialize = False
    else:
        logging.info("No manifest-versions checkout exists at %s", manifest_dir)

    if reinitialize:
        logging.info("Cloning fresh manifest-versions checkout.")
        osutils.RmDir(manifest_dir, ignore_missing=True)
        git.Clone(manifest_dir, manifest_repo)


def _PushGitChanges(git_repo, message, dry_run=False, push_to=None):
    """Push the final commit into the git repo.

    Args:
        git_repo: git repo to push
        message: Commit message
        dry_run: If true, don't actually push changes to the server
        push_to: A git.RemoteRef object specifying the remote branch to push to.
            Defaults to the tracking branch of the current branch.
    """
    if push_to is None:
        # TODO(akeshet): Clean up git.GetTrackingBranch to always or never
        # return a tuple.
        # pylint: disable=unpacking-non-sequence
        push_to = git.GetTrackingBranch(
            git_repo, for_checkout=False, for_push=True
        )

    git.RunGit(git_repo, ["add", "-A"])

    # It's possible that while we are running on dry_run, someone has already
    # committed our change.
    try:
        git.RunGit(git_repo, ["commit", "-m", message])
    except cros_build_lib.RunCommandError:
        if dry_run:
            return
        raise

    logging.info(
        "Pushing to branch (%s) with message: %s %s",
        push_to,
        message,
        " (dryrun)" if dry_run else "",
    )
    git.GitPush(git_repo, PUSH_BRANCH, push_to, skip=dry_run)


def CreateSymlink(src_file, dest_file):
    """Creates relative symlink from src to dest with optional removal of file.

    More robust symlink creation that creates a relative symlink from src_file
    to dest_file.

    This is useful for multiple calls of CreateSymlink where you are using
    the dest_file location to store information about the status of the
    src_file.

    Args:
        src_file: source for the symlink
        dest_file: destination for the symlink
    """
    dest_dir = os.path.dirname(dest_file)
    osutils.SafeUnlink(dest_file)
    osutils.SafeMakedirs(dest_dir)

    rel_src_file = os.path.relpath(src_file, dest_dir)
    logging.debug("Linking %s to %s", rel_src_file, dest_file)
    os.symlink(rel_src_file, dest_file)


def OfficialBuildSpecPath(version_info):
    """Generate an offical build version build spec file path.

    Args:
        version_info: VersionInfo instance describing the current version.

    Returns:
        Path for buildspec, relative to manifest_versions root.
    """
    return os.path.join(
        "buildspecs",
        str(version_info.chrome_branch),
        "%s.xml" % version_info.VersionString(),
    )


@retry_util.WithRetry(max_retry=20)
def _CommitAndPush(manifest_repo, git_url, buildspec, contents, dryrun):
    """Helper for committing and pushing buildspecs.

    Will create/checkout/clean the manifest_repo checkout at the given
    path with no assumptions about the previous state. It should NOT be
    considered clean when this function exits.

    Args:
        manifest_repo: Path to root of git repo for manifest_versions (int or
            ext).
        git_url: Git URL for remote git repository.
        buildspec: Relative path to buildspec in  repo.
        contents: String containing contents of buildspec manifest.
        dryrun: Git push --dry-run if set to True.

    Returns:
        Full path to buildspec created.
    """
    RefreshManifestCheckout(manifest_repo, git_url)

    filename = os.path.join(manifest_repo, buildspec)
    assert not os.path.exists(filename)

    git.CreatePushBranch(
        PUSH_BRANCH,
        manifest_repo,
        sync=False,
        remote_push_branch=git.RemoteRef("origin", "main"),
    )
    osutils.WriteFile(filename, contents, makedirs=True)

    git.RunGit(manifest_repo, ["add", "-A"])
    message = "Creating buildspec: %s" % buildspec
    git.RunGit(manifest_repo, ["commit", "-m", message])
    git.PushBranch(PUSH_BRANCH, manifest_repo, dryrun=dryrun)

    logging.info("Created buildspec: %s as %s", buildspec, filename)

    return filename


def PopulateAndPublishBuildSpec(
    rel_build_spec,
    manifest,
    manifest_versions_int,
    manifest_versions_ext=None,
    dryrun=True,
):
    """Create build spec based on current source checkout.

    This assumes that the current checkout is 100% clean, and that local SHAs
    exist in GoB.

    The new buildspec is created in manifest_versions and pushed remotely.

    The manifest_versions paths do not need to be in a clean state, but should
    be consistent from build to build for performance reasons.

    Args:
        rel_build_spec: Path relative to manifest_verions root for buildspec.
        manifest: Contents of the manifest to publish as a string.
        manifest_versions_int: Path to manifest-versions-internal checkout.
        manifest_versions_ext: Path to manifest-versions checkout (public).
        dryrun: Git push --dry-run if set to True.
    """
    site_params = config_lib.GetSiteParams()

    # Create and push internal buildspec.
    build_spec = _CommitAndPush(
        manifest_versions_int,
        site_params.MANIFEST_VERSIONS_INT_GOB_URL,
        rel_build_spec,
        manifest,
        dryrun,
    )

    if manifest_versions_ext:
        # Create the external only manifest in a tmp file, read into string.
        whitelisted_remotes = config_lib.GetSiteParams().EXTERNAL_REMOTES
        tmp_manifest = FilterManifest(
            build_spec, whitelisted_remotes=whitelisted_remotes
        )
        manifest_ext = osutils.ReadFile(tmp_manifest)

        _CommitAndPush(
            manifest_versions_ext,
            site_params.MANIFEST_VERSIONS_GOB_URL,
            rel_build_spec,
            manifest_ext,
            dryrun,
        )


def GenerateAndPublishOfficialBuildSpec(
    repo,
    incr_type,
    manifest_versions_int,
    manifest_versions_ext=None,
    dryrun=True,
):
    """Increment the ChromeOS version number, and publish matching build spec.

    This assumes that the current checkout is 100% clean, and that local SHAs
    exist in GoB.

    The new build spec is created in manifest-versions-internal, and an
    external/filtered version is created in manifest-versions.

    Args:
        repo: Repository.RepoRepository instance.
        incr_type: If this is an official build spec, how we should increment
            the version? See VersionInfo.
        manifest_versions_int: Path to manifest-versions-internal checkout.
        manifest_versions_ext: Path to manifest-versions checkout (public).
        dryrun: Git push --dry-run if set to True.

    Returns:
        Path for buildspec, relative to manifest_versions root.
    """
    version_info = chromeos_version.VersionInfo.from_repo(
        repo.directory, incr_type=incr_type
    )

    # Increment the version and push the new version file.
    version_info.IncrementVersion()
    msg = "Incremented to version: %s" % version_info.VersionString()
    version_info.UpdateVersionFile(msg, dryrun)

    build_spec_path = OfficialBuildSpecPath(version_info)

    logging.info("Creating buildspec: %s", build_spec_path)
    PopulateAndPublishBuildSpec(
        build_spec_path,
        repo.ExportManifest(mark_revision=True),
        manifest_versions_int,
        manifest_versions_ext,
        dryrun,
    )

    return build_spec_path


class BuildSpecsManager:
    """A Class to manage buildspecs and their states."""

    SLEEP_TIMEOUT = 1 * 60

    def __init__(
        self,
        source_repo,
        manifest_repo,
        build_names,
        incr_type,
        force,
        branch,
        manifest=constants.DEFAULT_MANIFEST,
        dry_run=True,
        config=None,
        metadata=None,
        buildstore=None,
        buildbucket_client=None,
    ):
        """Initializes a build specs manager.

        Args:
            source_repo: Repository object for the source code.
            manifest_repo: Manifest repository for manifest versions /
                buildspecs.
            build_names: Identifiers for the build. Must match SiteConfig
                entries. If multiple identifiers are provided, the first item in
                the list must be an identifier for the group.
            incr_type: How we should increment this version - build|branch|patch
            force: Create a new manifest even if there are no changes.
            branch: Branch this builder is running on.
            manifest: Manifest to use for checkout. E.g. 'full' or 'buildtools'.
            dry_run: Whether we actually commit changes we make or not.
            config: Instance of config_lib.BuildConfig. Config dict of this
                builder.
            metadata: Instance of metadata_lib.CBuildbotMetadata. Metadata of
                this builder.
            buildstore: BuildStore object to make DB calls.
            buildbucket_client: Instance of buildbucket_v2.BuildbucketV2 client.
        """
        self.cros_source = source_repo
        buildroot = source_repo.directory
        if manifest_repo.startswith(
            config_lib.GetSiteParams().INTERNAL_GOB_URL
        ):
            self.manifest_dir = os.path.join(
                buildroot, "manifest-versions-internal"
            )
        else:
            self.manifest_dir = os.path.join(buildroot, "manifest-versions")

        self.manifest_repo = manifest_repo
        self.build_names = build_names
        self.incr_type = incr_type
        self.force = force
        self.branch = branch
        self.manifest = manifest
        self.dry_run = dry_run
        self.config = config
        self.master = False if config is None else config.master
        self.metadata = metadata
        self.buildstore = buildstore
        self.buildbucket_client = buildbucket_client

        # Directories and specifications are set once we load the specs.
        self.buildspecs_dir = None
        self.all_specs_dir = None
        self.pass_dirs = None
        self.fail_dirs = None

        # Specs.
        self.latest = None
        self._latest_build = None
        self.latest_unprocessed = None
        self.compare_versions_fn = chromeos_version.VersionInfo.VersionCompare

        self.current_version = None
        self.rel_working_dir = ""

    def _LatestSpecFromList(self, specs):
        """Find the latest spec in a list of specs.

        Args:
            specs: List of specs.

        Returns:
            The latest spec if specs is non-empty.
            None otherwise.
        """
        if specs:
            return max(specs, key=self.compare_versions_fn)

    def _LatestSpecFromDir(self, version_info, directory):
        """Returns the latest buildspec that match '*.xml' in a directory.

        Args:
            version_info: A VersionInfo object which will provide a build prefix
                to match for.
            directory: Directory of the buildspecs.
        """
        if os.path.exists(directory):
            match_string = version_info.BuildPrefix() + "*.xml"
            specs = fnmatch.filter(os.listdir(directory), match_string)
            return self._LatestSpecFromList(
                [os.path.splitext(m)[0] for m in specs]
            )

    def RefreshManifestCheckout(self):
        """Checks out manifest versions into the manifest directory."""
        RefreshManifestCheckout(self.manifest_dir, self.manifest_repo)

    def InitializeManifestVariables(self, version_info=None, version=None):
        """Initializes manifest-related instance variables.

        Args:
            version_info: Info class for version information of cros. If None,
                version must be specified instead.
            version: Requested version. If None, build the latest version.

        Returns:
            Whether the requested version was found.
        """
        assert (
            version_info or version
        ), "version or version_info must be specified"
        working_dir = os.path.join(self.manifest_dir, self.rel_working_dir)
        specs_for_builder = os.path.join(
            working_dir, "build-name", "%(builder)s"
        )
        self.buildspecs_dir = os.path.join(working_dir, "buildspecs")

        # If version is specified, find out what Chrome branch it is on.
        if version is not None:
            dirs = glob.glob(
                os.path.join(self.buildspecs_dir, "*", version + ".xml")
            )
            if not dirs:
                return False
            assert len(dirs) <= 1, "More than one spec found for %s" % version
            dir_pfx = os.path.basename(os.path.dirname(dirs[0]))
            version_info = chromeos_version.VersionInfo(
                chrome_branch=dir_pfx, version_string=version
            )
        else:
            dir_pfx = version_info.chrome_branch

        self.all_specs_dir = os.path.join(self.buildspecs_dir, dir_pfx)
        self.pass_dirs, self.fail_dirs = [], []
        for build_name in self.build_names:
            specs_for_build = specs_for_builder % {"builder": build_name}
            self.pass_dirs.append(
                os.path.join(
                    specs_for_build, constants.BUILDER_STATUS_PASSED, dir_pfx
                )
            )
            self.fail_dirs.append(
                os.path.join(
                    specs_for_build, constants.BUILDER_STATUS_FAILED, dir_pfx
                )
            )

        # Calculate the status of the latest build, and whether the build was
        # processed.
        if version is None:
            self.latest = self._LatestSpecFromDir(
                version_info, self.all_specs_dir
            )
            if self.latest is not None:
                latest_builds = None
                if self.buildstore.AreClientsReady():
                    latest_builds = self.buildstore.GetBuildHistory(
                        self.build_names[0], 1, platform_version=self.latest
                    )
                if not latest_builds:
                    self.latest_unprocessed = self.latest
                else:
                    self._latest_build = latest_builds[0]

        return True

    def GetCurrentVersionInfo(self):
        """Returns the current version info from the version file."""
        version_file_path = self.cros_source.GetRelativePath(
            constants.VERSION_FILE
        )
        return chromeos_version.VersionInfo(
            version_file=version_file_path, incr_type=self.incr_type
        )

    def HasCheckoutBeenBuilt(self):
        """Checks to see if we've previously built this checkout."""
        if (
            self._latest_build
            and self._latest_build["status"] == constants.BUILDER_STATUS_PASSED
        ):
            latest_spec_file = "%s.xml" % os.path.join(
                self.all_specs_dir, self.latest
            )
            logging.info(
                "Found previous successful build manifest: %s", latest_spec_file
            )
            # We've built this checkout before if the manifest isn't different
            # than the last one we've built.
            to_return = not self.cros_source.IsManifestDifferent(
                latest_spec_file
            )
            logging.info(
                "Is this checkout the same as the last build: %s", to_return
            )
            return to_return
        else:
            # We've never built this manifest before so this checkout is always
            # new.
            logging.info("No successful build on this branch before")
            return False

    def CreateManifest(self):
        """Returns the path to a new manifest based on the current checkout."""
        new_manifest = tempfile.mkstemp("manifest_versions.manifest")[1]
        osutils.WriteFile(
            new_manifest, self.cros_source.ExportManifest(mark_revision=True)
        )
        return new_manifest

    def GetNextVersion(self, version_info):
        """Returns the next version string that should be built."""
        version = version_info.VersionString()
        if self.latest == version:
            message = (
                "Automatic: %s - Updating to a new version number from %s"
                % (self.build_names[0], version)
            )
            if not self.dry_run:
                version = version_info.IncrementVersion()
                assert version != self.latest
                logging.info("Incremented version number to  %s", version)
            version_info.UpdateVersionFile(message, dry_run=self.dry_run)
        else:
            # See https://crbug.com/927911
            logging.info(
                "Version file does not match, not updating. Latest from"
                " buildspec is %s but chromeos_version.sh has %s.",
                self.latest,
                version,
            )

        return version

    def PublishManifest(self, manifest, version, build_id=None):
        """Publishes the manifest as the manifest for the version to others.

        Args:
            manifest: Path to manifest file to publish.
            version: Manifest version string, e.g. 6102.0.0-rc4
            build_id: Optional integer giving build_id of the build that is
                publishing this manifest. If specified and non-negative,
                build_id will be included in the commit message.
        """
        # Note: This commit message is used by master.cfg for figuring out when
        # to trigger slave builders.
        commit_message = "Automatic: Start %s %s %s" % (
            self.build_names[0],
            self.branch,
            version,
        )
        if build_id is not None and build_id >= 0:
            commit_message += "\nCrOS-Build-Id: %s" % build_id

        logging.info("Publishing build spec for: %s", version)
        logging.info("Publishing with commit message: %s", commit_message)
        logging.debug(
            "Manifest contents below.\n%s", osutils.ReadFile(manifest)
        )

        # Copy the manifest into the manifest repository.
        spec_file = "%s.xml" % os.path.join(self.all_specs_dir, version)
        osutils.SafeMakedirs(os.path.dirname(spec_file))

        shutil.copyfile(manifest, spec_file)

        # Actually push the manifest.
        self.PushSpecChanges(commit_message)

    def DidLastBuildFail(self):
        """Returns True if the last build failed."""
        return (
            self._latest_build
            and self._latest_build["status"] == constants.BUILDER_STATUS_FAILED
        )

    def WaitForSlavesToComplete(
        self,
        master_build_identifier,
        builders_array,
        timeout=3 * 60,
        ignore_timeout_exception=True,
    ):
        """Wait for all slaves to complete or timeout.

        This method checks the statuses of important builds in |builders_array|,
        waits for the builds to complete or timeout after given |timeout|.
        Builds marked as experimental through the tree status will not be
        considered in deciding whether to wait.

        Args:
            master_build_identifier: Master build identifier to check.
            builders_array: The name list of the build configs to check.
            timeout: Number of seconds to wait for the results.
            ignore_timeout_exception: Whether to ignore when the timeout
                exception is raised in waiting. Default to True.
        """
        builders_array = buildbucket_v2.FetchCurrentSlaveBuilders(
            self.config, self.metadata, builders_array
        )
        logging.info(
            "Waiting for the following builds to complete: %s", builders_array
        )

        if not builders_array:
            return

        start_time = datetime.datetime.now()

        def _PrintRemainingTime(remaining):
            logging.info("%s until timeout...", remaining)

        slave_status = build_status.SlaveStatus(
            start_time,
            builders_array,
            master_build_identifier,
            buildstore=self.buildstore,
            config=self.config,
            metadata=self.metadata,
            buildbucket_client=self.buildbucket_client,
            version=self.current_version,
            dry_run=self.dry_run,
        )

        try:
            timeout_util.WaitForSuccess(
                lambda x: slave_status.ShouldWait(),
                slave_status.UpdateSlaveStatus,
                timeout,
                period=self.SLEEP_TIMEOUT,
                side_effect_func=_PrintRemainingTime,
            )
        except timeout_util.TimeoutError as e:
            logging.error(
                "Not all builds finished before timeout (%d minutes) reached.",
                int((timeout / 60.0) + 0.5),
            )

            if not ignore_timeout_exception:
                raise e

    def GetLatestPassingSpec(self):
        """Get the last spec file that passed in the current branch."""
        version_info = self.GetCurrentVersionInfo()
        return self._LatestSpecFromDir(version_info, self.pass_dirs[0])

    def GetLocalManifest(self, version=None):
        """Return path to local copy of manifest given by version.

        Returns:
            Path of |version|.  By default if version is not set, returns the
            path of the current version.
        """
        if not self.all_specs_dir:
            raise BuildSpecsValueError(
                "GetLocalManifest failed, BuildSpecsManager "
                "instance not yet initialized by call to "
                "InitializeManifestVariables."
            )
        if version:
            return os.path.join(self.all_specs_dir, version + ".xml")
        elif self.current_version:
            return os.path.join(
                self.all_specs_dir, self.current_version + ".xml"
            )

        return None

    def BootstrapFromVersion(self, version):
        """Initialize manifest from a release version, returning its path."""
        # Only refresh the manifest checkout if needed.
        if not self.InitializeManifestVariables(version=version):
            self.RefreshManifestCheckout()
            if not self.InitializeManifestVariables(version=version):
                raise BuildSpecsValueError(
                    "Failure in BootstrapFromVersion. "
                    "InitializeManifestVariables failed after "
                    "RefreshManifestCheckout for version "
                    "%s." % version
                )

        # Return the current manifest.
        self.current_version = version
        return self.GetLocalManifest(self.current_version)

    def CheckoutSourceCode(self):
        """Syncs the cros source to the latest git hashes for the branch."""
        self.cros_source.Sync(self.manifest)

    def GetNextBuildSpec(self, retries=NUM_RETRIES, build_id=None):
        """Returns a path to the next manifest to build.

        Args:
            retries: Number of retries for updating the status.
            build_id: Optional integer cidb id of this build, which will be used
                to annotate the manifest-version commit if one is created.

        Raises:
            GenerateBuildSpecException in case of failure to generate a
            buildspec
        """
        last_error = None
        for index in range(0, retries + 1):
            try:
                self.CheckoutSourceCode()

                version_info = self.GetCurrentVersionInfo()
                self.RefreshManifestCheckout()
                self.InitializeManifestVariables(version_info)

                if not self.force and self.HasCheckoutBeenBuilt():
                    logging.info(
                        "Build is not forced and this checkout already built"
                    )
                    return None

                # If we're the master, always create a new build spec.
                # Otherwise, only create a new build spec if we've already built
                # the existing spec.
                if self.master or not self.latest_unprocessed:
                    logging.info(
                        "Build is master or build latest unprocessed is None"
                    )
                    git.CreatePushBranch(
                        PUSH_BRANCH, self.manifest_dir, sync=False
                    )
                    version = self.GetNextVersion(version_info)
                    new_manifest = self.CreateManifest()
                    logging.info("Publishing the new manifest version")
                    self.PublishManifest(
                        new_manifest, version, build_id=build_id
                    )
                else:
                    version = self.latest_unprocessed

                self.current_version = version
                logging.info("current_version: %s", self.current_version)
                to_return = self.GetLocalManifest(version)
                logging.info("Local manifest for version: %s", to_return)
                return to_return
            except cros_build_lib.RunCommandError as e:
                last_error = "Failed to generate buildspec. error: %s" % e
                logging.error(last_error)
                logging.error(
                    "Retrying to generate buildspec:  Retry %d/%d",
                    index + 1,
                    retries,
                )

        # Cleanse any failed local changes and throw an exception.
        self.RefreshManifestCheckout()
        raise GenerateBuildSpecException(last_error)

    def _SetPassSymlinks(self, success_map):
        """Marks the buildspec as passed by creating a symlink in passed dir.

        Args:
            success_map: Map of config names to whether they succeeded.
        """
        src_file = "%s.xml" % os.path.join(
            self.all_specs_dir, self.current_version
        )
        for i, build_name in enumerate(self.build_names):
            if success_map[build_name]:
                sym_dir = self.pass_dirs[i]
            else:
                sym_dir = self.fail_dirs[i]
            dest_file = "%s.xml" % os.path.join(sym_dir, self.current_version)
            status = builder_status_lib.BuilderStatus.GetCompletedStatus(
                success_map[build_name]
            )
            logging.debug("Build %s: %s -> %s", status, src_file, dest_file)
            CreateSymlink(src_file, dest_file)

    def PushSpecChanges(self, commit_message):
        """Pushes any changes you have in the manifest directory.

        Args:
            commit_message: Message that the git commit will contain.
        """
        # %submit enables Gerrit automerge feature to manage contention on the
        # high traffic manifest_versions repository.
        push_to_git = git.GetTrackingBranch(
            self.manifest_dir, for_checkout=False, for_push=False
        )
        push_to = git.RemoteRef(
            push_to_git.remote,
            f"refs/for/{push_to_git.ref}%submit",
            push_to_git.project_name,
        )
        _PushGitChanges(
            self.manifest_dir,
            commit_message,
            dry_run=self.dry_run,
            push_to=push_to,
        )

    def UpdateStatus(self, success_map, message=None, retries=NUM_RETRIES):
        """Updates the status of the build for the current build spec.

        Args:
            success_map: Map of config names to whether they succeeded.
            message: Message accompanied with change in status.
            retries: Number of retries for updating the status
        """
        last_error = None
        if message:
            logging.info("Updating status with message %s", message)
        for index in range(0, retries + 1):
            try:
                self.RefreshManifestCheckout()
                git.CreatePushBranch(PUSH_BRANCH, self.manifest_dir, sync=False)
                success = all(success_map.values())
                commit_message = (
                    "Automatic checkin: status=%s build_version %s for %s"
                    % (
                        builder_status_lib.BuilderStatus.GetCompletedStatus(
                            success
                        ),
                        self.current_version,
                        self.build_names[0],
                    )
                )

                self._SetPassSymlinks(success_map)

                self.PushSpecChanges(commit_message)
                return
            except cros_build_lib.RunCommandError as e:
                last_error = (
                    "Failed to update the status for %s during remote"
                    " command: %s" % (self.build_names[0], e)
                )
                logging.error(last_error)
                logging.error(
                    "Retrying to update the status:  Retry %d/%d",
                    index + 1,
                    retries,
                )

        # Cleanse any failed local changes and throw an exception.
        self.RefreshManifestCheckout()
        raise StatusUpdateException(last_error)


def _GetDefaultRemote(manifest_dom):
    """Returns the default remote in a manifest (if any).

    Args:
        manifest_dom: DOM Document object representing the manifest.

    Returns:
        Default remote if one exists, None otherwise.
    """
    default_nodes = manifest_dom.getElementsByTagName(DEFAULT_ELEMENT)
    if default_nodes:
        if len(default_nodes) > 1:
            raise FilterManifestException(
                "More than one <default> element found in manifest"
            )
        return default_nodes[0].getAttribute(PROJECT_REMOTE_ATTR)
    return None


def _GetGroups(project_element):
    """Returns the default remote in a manifest (if any).

    Args:
        project_element: DOM Document object representing a project.

    Returns:
        List of names of the groups the project belongs too.
    """
    group = project_element.getAttribute(PROJECT_GROUP_ATTR)
    if not group:
        return []

    return [s.strip() for s in group.split(",")]


def FilterManifest(manifest, whitelisted_remotes=None, whitelisted_groups=None):
    """Returns a path to a new manifest with whitelists enforced.

    Args:
        manifest: Path to an existing manifest that should be filtered.
        whitelisted_remotes: Tuple of remotes to allow in the generated
            manifest. Only projects with those remotes will be included in the
            external manifest. (None means all remotes are acceptable)
        whitelisted_groups: Tuple of groups to allow in the generated manifest.
            (None means all groups are acceptable)

    Returns:
        Path to a new manifest that is a filtered copy of the original.
    """
    temp_fd, new_path = tempfile.mkstemp("external_manifest")
    manifest_dom = minidom.parse(manifest)
    manifest_node = manifest_dom.getElementsByTagName(MANIFEST_ELEMENT)[0]
    remotes = manifest_dom.getElementsByTagName(REMOTE_ELEMENT)
    projects = manifest_dom.getElementsByTagName(PROJECT_ELEMENT)
    pending_commits = manifest_dom.getElementsByTagName(PALADIN_COMMIT_ELEMENT)

    default_remote = _GetDefaultRemote(manifest_dom)

    # Remove remotes that don't match our whitelist.
    for remote_element in remotes:
        name = remote_element.getAttribute(REMOTE_NAME_ATTR)
        if (
            name is not None
            and whitelisted_remotes
            and name not in whitelisted_remotes
        ):
            manifest_node.removeChild(remote_element)

    filtered_projects = set()
    for project_element in projects:
        project_remote = project_element.getAttribute(PROJECT_REMOTE_ATTR)
        project = project_element.getAttribute(PROJECT_NAME_ATTR)
        if not project_remote:
            if not default_remote:
                # This should not happen for a valid manifest. Either each
                # project must have a remote specified or there should
                # be manifest default we could use.
                raise FilterManifestException(
                    "Project %s has unspecified remote with no default"
                    % project
                )
            project_remote = default_remote

        groups = _GetGroups(project_element)

        filter_remote = (
            whitelisted_remotes and project_remote not in whitelisted_remotes
        )

        filter_group = whitelisted_groups and not any(
            g in groups for g in whitelisted_groups
        )

        if filter_remote or filter_group:
            filtered_projects.add(project)
            manifest_node.removeChild(project_element)

    for commit_element in pending_commits:
        if (
            commit_element.getAttribute(PALADIN_PROJECT_ATTR)
            in filtered_projects
        ):
            manifest_node.removeChild(commit_element)

    with os.fdopen(temp_fd, "w") as manifest_file:
        # Filter out empty lines.
        lines = manifest_dom.toxml("utf-8").decode("utf-8").splitlines()
        stripped = [x.strip() for x in lines]
        filtered_manifest_noempty = [x for x in stripped if x]
        manifest_file.write(os.linesep.join(filtered_manifest_noempty))

    return new_path
