# 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 __call__(self, step_name, cmd):
    self._ensure()
    full_cmd = [self._bsdtar_path] + list(cmd)
    return self.m.step(step_name, full_cmd)

  def _ensure(self, version=None):
    """Ensures that bsdtar is installed."""
    if self._bsdtar_path:
      return
    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')

  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.
    """
    # 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(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."""
    cmd = ['--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(step_name, cmd)
    self._module.m.path.mock_add_paths(self._path)
    return step_result
