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

# TODO: Support cleaning /build/*/tmp.
# TODO: Support running `eclean -q packages` on / and the sysroots.
# TODO: Support cleaning sysroots as a destructive option.

"""Clean up working files in a Chromium OS checkout.

If unsure, just use the --safe flag to clean out various objects.
"""

import errno
import glob
import logging
import os
from pathlib import Path

from chromite.cli import command
from chromite.lib import chroot_lib
from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import dev_server_wrapper
from chromite.lib import osutils
from chromite.lib import path_util
from chromite.utils import pformat
from chromite.utils import timer


@command.command_decorator("clean")
class CleanCommand(command.CliCommand):
    """Clean up working files from the build."""

    use_dryrun_options = True

    @classmethod
    def AddParser(cls, parser) -> None:
        """Add parser arguments."""
        super(CleanCommand, cls).AddParser(parser)

        parser.add_argument(
            "--safe",
            default=False,
            action="store_true",
            help="Clean up files that are automatically created.",
        )

        group = parser.add_argument_group(
            "Cache Selection (Advanced)",
            description="Clean out specific caches (--safe does all of these).",
        )
        group.add_argument(
            "--cache",
            default=False,
            action="store_true",
            help="Clean up our shared cache dir.",
        )
        group.add_argument(
            "--chromite",
            default=False,
            action="store_true",
            help="Clean up chromite working directories.",
        )
        group.add_argument(
            "--deploy",
            default=False,
            action="store_true",
            help="Clean files cached by cros deploy.",
        )
        group.add_argument(
            "--flash",
            default=False,
            action="store_true",
            help="Clean files cached by cros flash.",
        )
        group.add_argument(
            "--images",
            default=False,
            action="store_true",
            help="Clean up locally generated images.",
        )
        group.add_argument(
            "--incrementals",
            default=False,
            action="store_true",
            help="Clean up incremental package objects.",
        )
        group.add_argument(
            "--logs",
            default=False,
            action="store_true",
            help="Clean up various build log files.",
        )
        group.add_argument(
            "--workdirs",
            default=False,
            action="store_true",
            help="Clean up build various package build directories.",
        )
        group.add_argument(
            "--chroot-tmp",
            default=False,
            action="store_true",
            help="Empty the chroot's /tmp directory.",
        )

        group = parser.add_argument_group(
            "Unrecoverable Options (Dangerous)",
            description="Clean out objects that cannot be recovered easily.",
        )
        group.add_argument(
            "--clobber",
            default=False,
            action="store_true",
            help="Delete all non-source objects.",
        )
        group.add_argument(
            "--chroot",
            default=False,
            action="store_true",
            help="Delete build chroot (affects all boards).",
        )
        group.add_argument(
            "--board", action="append", help="Delete board(s) sysroot(s)."
        )
        group.add_argument(
            "--sysroots",
            default=False,
            action="store_true",
            help="Delete ALL of the sysroots. This is the same as calling with "
            "--board with every board that has been built.",
        )
        group.add_argument(
            "--autotest",
            default=False,
            action="store_true",
            help="Delete build_externals packages.",
        )

        group = parser.add_argument_group(
            "Advanced Customization",
            description="Advanced options that are rarely needed.",
        )
        group.add_argument(
            "--sdk-path",
            type="str_path",
            default=constants.DEFAULT_CHROOT_PATH,
            help="The sdk (chroot) path. This only needs to be provided if "
            "your chroot is not in the default location.",
        )
        group.add_argument(
            "--out-path",
            type="str_path",
            default=constants.DEFAULT_OUT_PATH,
            help="The sdk state/output path. This only needs to be provided if"
            " your sdk state is not in the default location.",
        )

    def __init__(self, options) -> None:
        """Initializes cros clean."""
        command.CliCommand.__init__(self, options)

    @classmethod
    def ProcessOptions(cls, parser, options) -> None:
        """Post process options."""
        # If no option is set, default to "--safe".
        if not (
            options.autotest
            or options.board
            or options.cache
            or options.chromite
            or options.chroot
            or options.chroot_tmp
            or options.clobber
            or options.deploy
            or options.flash
            or options.images
            or options.incrementals
            or options.logs
            or options.safe
            or options.sysroots
            or options.workdirs
        ):
            options.safe = True

        if options.clobber:
            options.chroot = True
            options.autotest = True
            options.safe = True

        if options.safe:
            options.cache = True
            options.chromite = True
            options.chroot_tmp = True
            options.deploy = True
            options.flash = True
            options.images = True
            options.incrementals = True
            options.logs = True
            options.workdirs = True

    @timer.timed("Cros Clean", logging.debug)
    def Run(self) -> None:
        """Perform the cros clean command."""
        chroot = chroot_lib.Chroot(
            self.options.sdk_path, out_path=Path(self.options.out_path)
        )

        cros_build_lib.AssertOutsideChroot()

        total_size = 0

        def _GetSize(path):
            """Calculate human size used by |path|."""
            nonlocal total_size
            result = cros_build_lib.dbg_run(
                ["du", "--bytes", "--summarize", path],
                check=False,
                capture_output=True,
                encoding="utf-8",
            )
            size = int(result.stdout.split()[0])
            total_size += size
            return pformat.size(size)

        def _LogClean(path) -> None:
            if not os.path.exists(path):
                return
            logging.notice("would have cleaned: %s (%s)", path, _GetSize(path))

        def Clean(path, ignore_mount=False) -> None:
            """Helper wrapper for the dry-run checks"""
            if ignore_mount and os.path.ismount(path):
                logging.debug("Ignoring bind mounted dir: %s", path)
            elif self.options.dryrun:
                _LogClean(path)
            else:
                osutils.RmDir(path, ignore_missing=True, sudo=True)

        def _LogEmpty(path) -> None:
            if not os.path.exists(path):
                return
            logging.notice("would have emptied: %s (%s)", path, _GetSize(path))

        def Empty(path, ignore_mount=False) -> None:
            """Helper wrapper for the dry-run checks"""
            if ignore_mount and os.path.ismount(path):
                logging.debug("Ignoring bind mounted dir: %s", path)
            elif self.options.dryrun:
                _LogEmpty(path)
            else:
                osutils.EmptyDir(path, ignore_missing=True, sudo=True)

        # Delete this first since many of the caches below live in the chroot.
        if self.options.chroot:
            logging.debug("Remove the chroot.")
            if self.options.dryrun:
                logging.notice("would have cleaned: %s", chroot.path)
            else:
                with timer.timer("Remove the chroot", logging.debug):
                    cros_build_lib.run(["cros_sdk", "--delete"])

        boards = self.options.board or []
        if self.options.sysroots:
            try:
                boards = os.listdir(chroot.full_path("build"))
            except OSError as e:
                if e.errno != errno.ENOENT:
                    raise
        if boards:
            with timer.timer("Clean Sysroots", logging.debug):
                for b in boards:
                    logging.debug("Clean up the %s sysroot.", b)
                    with timer.timer(
                        f"Clean up the {b} sysroot.", logging.debug
                    ):
                        Clean(chroot.full_path("build", b))

        if self.options.chroot_tmp:
            logging.debug("Empty chroot tmp directory.")
            with timer.timer("Empty chroot tmp directory", logging.debug):
                Empty(chroot.tmp)

        if self.options.cache:
            logging.debug("Clean the global cache.")
            with timer.timer("Clean the global cache", logging.debug):
                Empty(path_util.get_global_cache_dir(), ignore_mount=True)

            logging.debug("Clean the common cache.")
            with timer.timer("Clean the common cache", logging.debug):
                Empty(self.options.cache_dir, ignore_mount=True)

            # Recreate dirs that cros_sdk does when entering.
            # TODO: When sdk_lib/enter_chroot.sh is moved to chromite, we should
            # unify with those code paths.
            if not self.options.dryrun:
                # Prior to recreating the distfiles directory we must ensure
                # that the cache directory is not root.
                osutils.SafeMakedirsNonRoot(self.options.cache_dir)
                distfiles_dir = os.path.join(
                    self.options.cache_dir, "distfiles"
                )
                osutils.SafeMakedirs(distfiles_dir)
                os.chmod(distfiles_dir, 0o2775)

                # The host & target subdirs aren't used anymore since we unified
                # them, # but if the cache is shared with older branches, we
                # don't want to have files duplicated in them.  The unification
                # happened in Jul 2020 for # 13360.0.0+ / R86+, so we can prob
                # drop this logic ~Jul 2028?
                for subdir in ("host", "target"):
                    subdir = os.path.join(distfiles_dir, subdir)
                    # Recreate the path if it isn't a symlink.
                    if not os.path.islink(subdir):
                        osutils.RmDir(subdir, ignore_missing=True, sudo=True)
                        # Have the subdirs point to the common (parent) dir.
                        os.symlink(".", subdir)

                ccache_dir = os.path.join(distfiles_dir, "ccache")
                osutils.SafeMakedirs(ccache_dir)
                os.chmod(ccache_dir, 0o2775)

        if self.options.chromite:
            logging.debug("Clean chromite workdirs.")
            with timer.timer("Clean chromite workdirs", logging.debug):
                Clean(constants.CHROMITE_DIR / "venv" / "venv")
                Clean(constants.CHROMITE_DIR / "venv" / ".venv_lock")

        if self.options.deploy:
            logging.debug("Clean up the cros deploy cache.")
            with timer.timer("Clean up the cros deploy cache", logging.debug):
                for subdir in ("custom-packages", "gmerge-packages"):
                    for d in glob.glob(chroot.full_path("build", "*", subdir)):
                        Clean(d)

        if self.options.flash:
            if self.options.dryrun:
                _LogClean(dev_server_wrapper.DEFAULT_STATIC_DIR)
            else:
                with timer.timer(
                    dev_server_wrapper.DEFAULT_STATIC_DIR, logging.debug
                ):
                    dev_server_wrapper.DevServerWrapper.WipeStaticDirectory()

        if self.options.images:
            logging.debug("Clean the images cache.")
            cache_dir = constants.DEFAULT_BUILD_ROOT
            with timer.timer("Clean the images cache", logging.debug):
                Clean(cache_dir, ignore_mount=True)

        if self.options.incrementals:
            logging.debug("Clean package incremental objects.")
            with timer.timer(
                "Clean package incremental objects", logging.debug
            ):
                Empty(chroot.full_path("var", "cache", "portage"))
                for d in glob.glob(
                    chroot.full_path("build", "*", "var", "cache", "portage")
                ):
                    Empty(d)
                for d in glob.glob(
                    chroot.full_path(
                        "var",
                        "cache",
                        "chromeos-chrome",
                        "*",
                        "src",
                        "out_*",
                    )
                ):
                    Clean(d)

        if self.options.logs:
            logging.debug("Clean log files.")
            with timer.timer("Clean log files", logging.debug):
                Empty(chroot.full_path("var", "log"))
                for d in glob.glob(
                    chroot.full_path("build", "*", "tmp", "portage", "logs")
                ):
                    Empty(d)

        if self.options.workdirs:
            logging.debug("Clean package workdirs.")
            with timer.timer("Clean package workdirs", logging.debug):
                Clean(chroot.full_path("var", "tmp", "portage"))
                Clean(constants.CHROMITE_DIR / "venv" / "venv")
                for d in glob.glob(
                    chroot.full_path("build", "*", "tmp", "portage")
                ):
                    Clean(d)

        if self.options.autotest:
            logging.debug("Clean build_externals.")
            with timer.timer("Clean build_externals", logging.debug):
                packages_dir = os.path.join(
                    constants.SOURCE_ROOT,
                    "src",
                    "third_party",
                    "autotest",
                    "files",
                    "site-packages",
                )
                Clean(packages_dir)

        if total_size:
            logging.notice(
                "Freed %s (apparent) space", pformat.size(total_size)
            )
