# Copyright 2017 The Fuchsia 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 recipe_engine import recipe_api


class TarApi(recipe_api.RecipeApi):
    """Provides steps to tar and untar files."""

    COMPRESSION_OPTS = ["gzip", "bzip2", "xz", "lzma"]

    def __call__(self, step_name, cmd):
        full_cmd = [self._bsdtar_path] + list(cmd)
        return self.m.step(step_name, full_cmd)

    @property
    def _bsdtar_path(self):
        """Ensures that bsdtar is installed."""
        return self.m.ensure_tool("bsdtar", self.resource("tool_manifest.json"))

    def create(self, path, compression=None):
        """Returns TarArchive object that can be used to compress a set of files.

        Args:
          path: path of the archive file to be created.
          compression: str, one of COMPRESSION_OPTS or None to disable compression.
        """
        assert not compression or compression in TarApi.COMPRESSION_OPTS, (
            "compression must be one of %s",
            TarApi.COMPRESSION_OPTS,
        )
        return TarArchive(self.m, path, compression)

    def extract(self, step_name, path, directory=None, strip_components=None):
        """Uncompress |archive| file.

        Args:
          step_name: name of the step.
          path: absolute path to archive file.
          directory: directory to extract the archive in.
          strip_components: strip number of leading components from file names.
        """
        # We use long-form options whenever possible, but for options with
        # arguments, we have to use the short form. The recipe engine tests require
        # objects which might be placeholders (in this case |path|) to be their own
        # argument, and the version of tar we're using doesn't support
        # '--long-opt arg'. It only supports '--long-opt=arg' or short-form like
        # '-s arg'.
        cmd = [
            "--extract",
            "--verbose",
            "-f",
            path,
        ]
        if directory:
            cmd.extend(["-C", directory])
        if strip_components:
            cmd.extend(["--strip-components", str(int(strip_components))])
        return self(step_name, cmd)


class TarArchive:
    """Used to gather a list of files to tar."""

    def __init__(self, api, path, compression):
        self._api = api
        self._path = path
        self._compression = compression
        self._entries = {}

    @property
    def path(self):
        return self._path

    def add(self, path, directory=None):
        """Stages single file to be added to the package.

        Args:
          path: absolute path to a file, should be a child of |directory|.
          directory: ancestor directory of |path|. The name of the file
              inside the archive will not include |directory|. Defaults to $CWD.
        """
        if not directory:
            directory = self._api.context.cwd
        assert directory.is_parent_of(
            path
        ), "directory must be a parent of path. directory: %s.%s, path: %s.%s" % (
            directory.base,
            directory.pieces,
            path.base,
            path.pieces,
        )
        self._entries.setdefault(str(directory), []).append(str(path))

    def tar(self, step_name):
        """Step to tar all staged files."""
        cmd = ["--create", "-f", self._path]
        if self._compression:
            cmd.append("--%s" % self._compression)
        for directory in sorted(self._entries):
            cmd.extend(
                ["-C", directory]
                + [
                    self._api.path.relpath(p, directory)
                    for p in self._entries[directory]
                ]
            )

        step_result = self._api.tar(step_name, cmd)
        self._api.path.mock_add_paths(self._path)
        return step_result
