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

"""Module containing SDK stages."""

import glob
import json
import logging
import os
import re

from chromite.cbuildbot import cbuildbot_alerts
from chromite.cbuildbot import commands
from chromite.cbuildbot import prebuilts
from chromite.cbuildbot.stages import generic_stages
from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import osutils
from chromite.lib import perf_uploader
from chromite.lib import portage_util
from chromite.scripts import upload_prebuilts


# Version of the Manifest file being generated for SDK artifacts. Should be
# incremented for major format changes.
PACKAGE_MANIFEST_VERSION = "1"

# Paths excluded when packaging SDK artifacts. These are relative to the target
# build root where SDK packages are being installed (e.g. /build/amd64-host).
PACKAGE_EXCLUDED_PATHS = (
    "usr/lib/debug",
    "usr/lib64/debug",
    constants.AUTOTEST_BUILD_PATH,
    "packages",
    "tmp",
)

# Names of various packaged artifacts.
SDK_TARBALL_NAME = "built-sdk.tar.xz"


def SdkPerfPath(buildroot):
    """Return the path to the perf file for sdk stages."""
    return os.path.join(
        buildroot, constants.DEFAULT_CHROOT_DIR, "tmp", "cros-sdk.perf"
    )


def CreateTarball(source_root, tarball_path, exclude_paths=None):
    """Packs |source_root| into |tarball_path|.

    Args:
      source_root: Path to the directory we want to package.
      tarball_path: Path of the tarball that should be created.
      exclude_paths: Subdirectories to exclude.
    """
    # TODO(zbehan): We cannot use xz from the chroot unless it's
    # statically linked.
    extra_args = None
    if exclude_paths is not None:
        extra_args = ["--anchored"]
        extra_args.extend("--exclude=./%s/*" % x for x in exclude_paths)
    # Options for maximum compression.
    extra_env = {"XZ_OPT": "-e9"}
    cros_build_lib.CreateTarball(
        tarball_path,
        source_root,
        sudo=True,
        extra_args=extra_args,
        debug_level=logging.INFO,
        extra_env=extra_env,
    )
    # Make sure the regular user has the permission to read.
    cmd = ["chmod", "a+r", tarball_path]
    cros_build_lib.sudo_run(cmd)


class SDKBuildToolchainsStage(
    generic_stages.BuilderStage, generic_stages.ArchivingStageMixin
):
    """Stage that builds all the cross-compilers we care about"""

    category = constants.PRODUCT_TOOLCHAIN_STAGE

    def PerformStage(self):
        chroot_location = os.path.join(
            self._build_root, constants.DEFAULT_CHROOT_DIR
        )

        # Build the toolchains first.  Since we're building & installing the
        # compilers, need to run as root.
        self.CrosSetupToolchains(
            ["--nousepkg"], sudo=True, extra_env=self._portage_extra_env
        )

        # Create toolchain packages.
        self.CreateRedistributableToolchains(chroot_location)
        toolchain_path = os.path.join(
            chroot_location, constants.SDK_TOOLCHAINS_OUTPUT
        )
        for files in os.listdir(toolchain_path):
            self.UploadArtifact(
                os.path.join(toolchain_path, files), strict=True, archive=True
            )

    def CrosSetupToolchains(self, cmd_args, **kwargs):
        """Wrapper around cros_setup_toolchains to simplify things."""
        commands.RunBuildScript(
            self._build_root,
            ["cros_setup_toolchains"] + list(cmd_args),
            chromite_cmd=True,
            enter_chroot=True,
            **kwargs,
        )

    def CreateRedistributableToolchains(self, chroot_location):
        """Create the toolchain packages"""
        osutils.RmDir(
            os.path.join(chroot_location, constants.SDK_TOOLCHAINS_OUTPUT),
            ignore_missing=True,
        )

        # We need to run this as root because the tool creates hard links to root
        # owned files and our bots enable security features which disallow that.
        # Specifically, these features cause problems:
        #  /proc/sys/kernel/yama/protected_nonaccess_hardlinks
        #  /proc/sys/fs/protected_hardlinks
        self.CrosSetupToolchains(
            [
                # TODO(crbug.com/917193): Enable debugging for now.
                "--debug",
                "--create-packages",
                "--output-dir",
                os.path.join("/", constants.SDK_TOOLCHAINS_OUTPUT),
            ],
            sudo=True,
        )


class SDKPackageStage(
    generic_stages.BuilderStage, generic_stages.ArchivingStageMixin
):
    """Stage that performs preparing and packaging SDK files"""

    category = constants.PRODUCT_TOOLCHAIN_STAGE

    def __init__(self, builder_run, buildstore, version=None, **kwargs):
        self.sdk_version = version
        super().__init__(builder_run, buildstore, **kwargs)

    def PerformStage(self):
        tarball_location = os.path.join(self._build_root, SDK_TARBALL_NAME)
        chroot_location = os.path.join(
            self._build_root, constants.DEFAULT_CHROOT_DIR
        )
        board_location = os.path.join(chroot_location, "build/amd64-host")
        manifest_location = tarball_location + ".Manifest"

        # Cleanup etc/make.conf.board_setup for use in SDK.
        self.CleanupMakeConfBoardSetup(board_location)

        # Create a tarball of the latest SDK.
        CreateTarball(
            board_location,
            tarball_location,
            exclude_paths=PACKAGE_EXCLUDED_PATHS,
        )
        self.UploadArtifact(tarball_location, strict=True, archive=True)

        # Create a package manifest for the tarball.
        self.CreateManifestFromSDK(board_location, manifest_location)

        self.SendPerfValues(tarball_location)

    def CreateManifestFromSDK(self, sdk_path, dest_manifest):
        """Creates a manifest from a given source chroot.

        Args:
          sdk_path: Path to the root of the SDK to describe.
          dest_manifest: Path to the manifest that should be generated.
        """
        logging.info("Generating manifest for new sdk")
        package_data = {}
        for key, version in portage_util.ListInstalledPackages(sdk_path):
            package_data.setdefault(key, []).append((version, {}))
        self._WriteManifest(package_data, dest_manifest)

    def _WriteManifest(self, data, manifest):
        """Encode manifest into a json file."""
        json_input = dict(version=PACKAGE_MANIFEST_VERSION, packages=data)
        osutils.WriteFile(manifest, json.dumps(json_input))

    def _SendPerfValues(
        self, buildroot, sdk_tarball, buildbot_uri_log, version, platform_name
    ):
        """Generate & upload perf data for the build"""
        perf_path = SdkPerfPath(buildroot)
        test_name = "sdk"
        units = "bytes"

        # Make sure the file doesn't contain previous data.
        osutils.SafeUnlink(perf_path)

        common_kwargs = {
            "higher_is_better": False,
            "graph": "cros-sdk-size",
            "stdio_uri": buildbot_uri_log,
        }

        sdk_size = os.path.getsize(sdk_tarball)
        perf_uploader.OutputPerfValue(
            perf_path, "base", sdk_size, units, **common_kwargs
        )

        for tarball in glob.glob(
            os.path.join(
                buildroot,
                constants.DEFAULT_CHROOT_DIR,
                constants.SDK_TOOLCHAINS_OUTPUT,
                "*.tar.*",
            )
        ):
            name = os.path.basename(tarball).rsplit(".", 2)[0]
            size = os.path.getsize(tarball)
            perf_uploader.OutputPerfValue(
                perf_path, name, size, units, **common_kwargs
            )
            perf_uploader.OutputPerfValue(
                perf_path,
                "base_plus_%s" % name,
                sdk_size + size,
                units,
                **common_kwargs,
            )

        # Due to limitations in the perf dashboard, we have to create an integer
        # based on the current timestamp.  This field only accepts integers, and
        # the perf dashboard accepts this or CrOS+Chrome official versions.
        revision = int(version.replace(".", ""))
        perf_values = perf_uploader.LoadPerfValues(perf_path)
        self._UploadPerfValues(
            perf_values, platform_name, test_name, revision=revision
        )

    def SendPerfValues(self, sdk_tarball):
        """Generate & upload perf data for the build"""
        self._SendPerfValues(
            self._build_root,
            sdk_tarball,
            self.ConstructDashboardURL(),
            self.sdk_version,
            self._run.bot_id,
        )

    def CleanupMakeConfBoardSetup(self, board_location):
        """Cleanup etc/make.conf.board_setup to be usable in the SDK"""
        board_setup = os.path.join(board_location, "etc/make.conf.board_setup")
        lines = osutils.ReadFile(board_setup).splitlines()

        to_remove = re.compile(r"^(ROOT|PKG_CONFIG)=")
        lines = [x for x in lines if not to_remove.match(x)]
        data = "\n".join(lines) + "\n"
        if "/build/" in data:
            logging.error("%s content:\n%s", board_setup, data)
            raise ValueError("/build/ paths must be cleaned from make.conf")
        osutils.WriteFile(board_setup, data, sudo=True)


class SDKTestStage(generic_stages.BuilderStage):
    """Stage that performs testing an SDK created in a previous stage"""

    option_name = "tests"
    category = constants.PRODUCT_TOOLCHAIN_STAGE

    def PerformStage(self):
        new_chroot_dir = "new-sdk-chroot"
        tarball_location = os.path.join(self._build_root, SDK_TARBALL_NAME)
        new_chroot_args = ["--chroot", new_chroot_dir]
        if self._run.options.chrome_root:
            new_chroot_args += ["--chrome_root", self._run.options.chrome_root]

        # Build a new SDK using the provided tarball.
        chroot_args = new_chroot_args + [
            "--download",
            "--replace",
            "--nousepkg",
            "--url",
            "file://" + tarball_location,
        ]
        cros_build_lib.run(
            ["true"],
            cwd=self._build_root,
            enter_chroot=True,
            chroot_args=chroot_args,
            extra_env=self._portage_extra_env,
        )

        # Inject the toolchain binpkgs from the previous sdk build.  On end user
        # systems, they'd be fetched from the binpkg mirror, but we don't have one
        # set up for this local build.
        pkgdir = os.path.join("var", "lib", "portage", "pkgs")
        old_pkgdir = os.path.join(
            self._build_root, constants.DEFAULT_CHROOT_DIR, pkgdir
        )
        new_pkgdir = os.path.join(self._build_root, new_chroot_dir, pkgdir)
        osutils.SafeMakedirs(new_pkgdir, sudo=True)
        cros_build_lib.sudo_run(
            ["cp", "-r"]
            + glob.glob(os.path.join(old_pkgdir, "*"))
            + [new_pkgdir]
        )

        # Now install those toolchains in the new chroot.  We skip the chroot
        # upgrade below which means we need to install the toolchain manually.
        cmd = [
            "cros_setup_toolchains",
            "--targets=boards",
            "--include-boards=%s" % ",".join(self._boards),
        ]
        commands.RunBuildScript(
            self._build_root,
            cmd,
            chromite_cmd=True,
            enter_chroot=True,
            sudo=True,
            chroot_args=new_chroot_args,
            extra_env=self._portage_extra_env,
        )

        # Build all the boards with the new sdk.
        for board in self._boards:
            cbuildbot_alerts.PrintBuildbotStepText(board)
            commands.SetupBoard(
                self._build_root,
                board,
                usepkg=True,
                chroot_upgrade=False,
                extra_env=self._portage_extra_env,
                chroot_args=new_chroot_args,
            )
            commands.Build(
                self._build_root,
                board,
                build_autotest=True,
                usepkg=False,
                extra_env=self._portage_extra_env,
                chroot_args=new_chroot_args,
                disable_revdep_logic=True,
            )


class SDKUprevStage(generic_stages.BuilderStage):
    """Stage that uprevs SDK version."""

    category = constants.PRODUCT_TOOLCHAIN_STAGE

    def __init__(self, builder_run, buildstore, version=None, **kwargs):
        super().__init__(builder_run, buildstore, **kwargs)
        self._version = version

    def PerformStage(self):
        cbuildbot_alerts.PrintBuildbotStepText(self._version)

        if self._run.config.prebuilts == constants.PUBLIC:
            binhost_conf_dir = constants.PUBLIC_BINHOST_CONF_DIR
        else:
            binhost_conf_dir = constants.PRIVATE_BINHOST_CONF_DIR
        sdk_conf = os.path.join(
            self._build_root, binhost_conf_dir, "host", "sdk_version.conf"
        )

        tc_path_format = prebuilts.GetToolchainSdkUploadFormat(
            self._version,
            prebuilts.GetToolchainSdkPaths(self._build_root)[0][1],
        )
        sdk_settings = {
            "SDK_LATEST_VERSION": self._version,
            "TC_PATH": tc_path_format % {"version": self._version},
        }
        if self._run.options.publish:
            upload_prebuilts.RevGitFile(
                sdk_conf, sdk_settings, dryrun=self._run.options.debug
            )
        else:
            logging.info(
                "Not updating sdk_version.conf because publishing was disabled."
            )
