# 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

import os


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

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

  def __init__(self, *args, **kwargs):
    super(TarApi, self).__init__(*args, **kwargs)
    self._bsdtar_path = None

  def ensure_tar(self, version=None):
    """Ensures that bsdtar is installed."""
    if self._bsdtar_path:
      return self._bsdtar_path

    with self.m.step.nest('ensure bsdtar'):
      with self.m.context(infra_steps=True):
        pkgs = self.m.cipd.EnsureFile()
        pkgs.add_package('fuchsia/tools/bsdtar/${platform}', version or 'latest')
        cipd_dir = self.m.path['start_dir'].join('cipd', 'bsdtar')
        self.m.cipd.ensure(cipd_dir, pkgs)
        self._bsdtar_path = cipd_dir.join('bsdtar')
        return self._bsdtar_path

  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, 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.
    """
    assert self._bsdtar_path
    # 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 = [
      self._bsdtar_path,
      '--extract',
      '--verbose',
      '-f',
      path,
    ]
    if directory:
      cmd.extend(['-C', directory])
    if strip_components:
      cmd.extend(['--strip-components', str(int(strip_components))])
    return self.m.step(step_name, cmd)


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

  def __init__(self, module, path, compression):
    self._module = module
    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._module.m.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."""
    assert self._module._bsdtar_path
    cmd = [
      self._module._bsdtar_path,
      '--create',
      '-f',
      self._path
    ]
    if self._compression:
      cmd.append('--%s' % self._compression)
    for directory in sorted(self._entries):
      cmd.extend(['-C', directory] + [
          os.path.relpath(p, directory) for p in self._entries[directory]])

    step_result = self._module.m.step(step_name, cmd)
    self._module.m.path.mock_add_paths(self._path)
    return step_result
