# 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
