# Copyright 2021 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.

"""Utility to tar Autotest and Tast artifacts from a given path, to a given path."""

import fnmatch
import os

from . import cmd_util

COMP_NONE = 0
COMP_GZIP = 1
COMP_BZIP2 = 2
COMP_XZ = 3


def _FindSourceRoot():
    """Try and find the root check out of the chromiumos tree"""
    source_root = path = os.path.realpath(os.path.join(
            os.path.abspath(__file__), '..', '..', '..'))
    while True:
        if os.path.isdir(os.path.join(path, '.repo')):
            return path
        elif path == '/':
            break
        path = os.path.dirname(path)
    return source_root


SOURCE_ROOT = _FindSourceRoot()



def FromChrootPath(chroot, file):
    return os.path.join(chroot, file)

def FromSysrootPath(sysroot, file):
    return os.path.join(sysroot, file)

def FindFilesMatching(pattern, target = './', cwd = os.curdir,
                      exclude_dirs=[]):
    """Search the root directory recursively for matching filenames.

    The |target| and |cwd| args allow manipulating how the found paths are
    returned as well as specifying where the search needs to be executed.

    If our filesystem only has /path/to/example.txt, and our pattern is '*.txt':
    |target|='./', |cwd|='/path'    =>  ./to/example.txt
    |target|='to', |cwd|='/path'    =>  to/example.txt
    |target|='./', |cwd|='/path/to' =>  ./example.txt
    |target|='/path'                =>  /path/to/example.txt
    |target|='/path/to'             =>  /path/to/example.txt

    Args:
      pattern: the pattern used to match the filenames.
      target: the target directory to search.
      cwd: current working directory.
      exclude_dirs: Directories to not include when searching.

    Returns:
      A list of paths of the matched files.
    """
    assert cwd
    assert os.path.exists(cwd)

    # Backup the current working directory before changing it.
    old_cwd = os.getcwd()
    os.chdir(cwd)

    matches = []
    for directory, _, filenames in os.walk(target):
        if any(directory.startswith(e) for e in exclude_dirs):
            # Skip files in excluded directories.
            continue

        for filename in fnmatch.filter(filenames, pattern):
            matches.append(os.path.join(directory, filename))

    # Restore the working directory.
    os.chdir(old_cwd)

    return matches


class AutotestTarballBuilder(object):
    """Builds autotest tarballs for testing."""

    # Archive file names.
    _SERVER_PACKAGE_ARCHIVE = 'autotest_server_package.tar.bz2'

    # Directory within _SERVER_PACKAGE_ARCHIVE where Tast files needed to run
    # with Server-Side Packaging are stored.
    _TAST_SUBDIR = 'tast'

    # Tast files and directories to include in AUTOTEST_SERVER_PACKAGE relative
    # to the build root.
    _TAST_FILES = [
            'usr/bin/tast',    # Main Tast executable.
            'usr/bin/remote_test_runner',    # Runs remote tests.
            'usr/libexec/tast/bundles',    # Dir containing test bundles.
            'usr/share/tast/data',    # Dir containing test data.
            'etc/tast/vars',    # Secret variables.
    ]
    # Tast files and directories stored in the source code.
    _TAST_SOURCE_FILES = [
            'src/platform/tast/tools/run_tast.sh',    # Helper to run tast.
    ]

    def __init__(self, archive_basedir, output_directory, chroot_path):
        """Init function.

        Args:
            archive_basedir (str): The base directory from which the archives
                will be created. This path should contain the `autotest`
                directory.
            output_directory (str): The directory where the archives will be
                written.
        """
        self.archive_basedir = archive_basedir
        self.output_directory = output_directory
        self.chroot_path = chroot_path

    def BuildFullAutotestandTastTarball(self):
        """Tar all needed Autotest & Tast files required by Docker Container.

        NOTE: This does not include autotest/packages, but will include all
        tests and client/deps.

        Returns:
            str|None - The path of the autotest server package tarball if
                created.
        """
        tast_files, transforms = self._GetTastServerFilesAndTarTransforms()
        autotest_files = FindFilesMatching(
            '*', target='autotest', cwd=self.archive_basedir,
            exclude_dirs=('autotest/packages',))

        tarball = os.path.join(self.output_directory,
                               self._SERVER_PACKAGE_ARCHIVE)
        if self._BuildTarball(autotest_files + tast_files, tarball,
                              extra_args=transforms):
            return tarball
        else:
            return None

    def _BuildTarball(self, input_list, tarball_path, extra_args=None):
        """Tar and zip files and directories from input_list to tarball_path.

        Args:
            input_list: A list of files and directories to be archived.
            tarball_path: Path of output tar archive file.
            compressed: Whether or not the tarball should be compressed with
                    pbzip2.
            **kwargs: Keyword arguments to pass to CreateTarball.

        Returns:
            Return value of CreateTarball.
        """
        for pathname in input_list:
            if os.path.exists(os.path.join(self.archive_basedir, pathname)):
                break
        else:
            # If any of them exist we can create an archive, but if none
            # do then we need to stop. For now, since we either pass in a
            # handful of directories we don't necessarily check, or actually
            # search the filesystem for lots of files, this is far more
            # efficient than building out a list of files that do exist.
            return None
        compressor = COMP_BZIP2
        chroot = self.chroot_path

        return cmd_util.CreateTarball(
            tarball_path, self.archive_basedir, compression=compressor,
            chroot=chroot, inputs=input_list, extra_args=extra_args)

    def _GetTastServerFilesAndTarTransforms(self):
        """Return Tast server files and corresponding tar transform flags.

        The returned paths should be included in AUTOTEST_SERVER_PACKAGE. The
        --transform arguments should be passed to GNU tar to convert the paths
        to appropriate destinations in the tarball.

        Returns:
            (files, transforms), where files is a list of absolute paths to
                Tast server files/directories and transforms is a list of
                --transform arguments to pass to GNU tar when archiving those
                files.
        """
        files = []
        transforms = []

        for path in self._GetTastFiles():
            if not os.path.exists(path):
                continue

            files.append(path)
            dest = os.path.join(self._TAST_SUBDIR, os.path.basename(path))
            transforms.append('--transform=s|^%s|%s|' %
                              (os.path.relpath(path, '/'), dest))

        return files, transforms

    def _GetTastFiles(self):
        """Build out the paths to the tast files.

        Returns:
            list[str] - The paths to the files.
        """
        files = []
        files.extend(FromChrootPath(self.chroot_path, x)
                     for x in self._TAST_FILES)

        for filename in self._TAST_SOURCE_FILES:
            files.append(os.path.join(SOURCE_ROOT, filename))

        return files
