# Copyright 2014 The Chromium 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 ZipApi(recipe_api.RecipeApi):
  """Provides steps to zip and unzip files."""

  def make_package(self, root, output):
    """Returns ZipPackage object that can be used to compress a set of files.

    Usage:
      pkg = api.zip.make_package(root, output)
      pkg.add_file(root.join('file'))
      pkg.add_directory(root.join('directory'))
      yield pkg.zip('zipping step')

    Args:
      root: a directory that would become root of a package, all files added to
          an archive will have archive paths relative to this directory.
      output: path to a zip file to create.

    Returns:
      ZipPackage object.
    """
    return ZipPackage(self.m, root, output)

  def directory(self, step_name, directory, output):
    """Step to compress a single directory.

    Args:
      step_name: display name of the step.
      directory: path to a directory to compress, it would become the root of
          an archive, i.e. |directory|/file.txt would be named 'file.txt' in
          the archive.
      output: path to a zip file to create.
    """
    pkg = self.make_package(directory, output)
    pkg.add_directory(directory)
    pkg.zip(step_name)

  def unzip(self, step_name, zip_file, output, quiet=False):
    """Step to uncompress |zip_file| into |output| directory.

    Zip package will be unpacked to |output| so that root of an archive is in
    |output|, i.e. archive.zip/file.txt will become |output|/file.txt.

    Step will FAIL if |output| already exists.

    Args:
      step_name: display name of a step.
      zip_file: path to a zip file to uncompress, should exist.
      output: path to a directory to unpack to, it should NOT exist.
      quiet (bool): If True, print terse output instead of the name
          of each unzipped file.
    """
    # TODO(vadimsh): Use 7zip on Windows if available?
    script_input = {
      'output': str(output),
      'zip_file': str(zip_file),
      'quiet': quiet,
    }
    self.m.step(
      step_name,
      [ 'python', self.resource('unzip.py') ],
      stdin=self.m.json.input(script_input)
    )


class ZipPackage(object):
  """Used to gather a list of files to zip."""

  def __init__(self, api, root, output):
    self._api = api
    self._root = root
    self._output = output
    self._entries = []

  @property
  def root(self):
    return self._root

  @property
  def output(self):
    return self._output

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

    Args:
      path: absolute path to a file, should be in |root| subdirectory.
      archive_name: name of the file in the archive, if non-None
    """
    assert self._root.is_parent_of(path), path
    self._entries.append({
      'type': 'file',
      'path': str(path),
      'archive_name': archive_name
    })

  def add_directory(self, path):
    """Stages a directory with all its content to be added to the package.

    Args:
      path: absolute path to a directory, should be in |root| subdirectory.
    """
    # TODO(vadimsh): Implement 'exclude' filter.
    assert self._root.is_parent_of(path) or path == self._root, path
    self._entries.append({
      'type': 'dir',
      'path': str(path),
    })

  def zip(self, step_name):
    """Step to zip all staged files."""
    script_input = {
      'entries': self._entries,
      'output': str(self._output),
      'root': str(self._root),
    }
    step_result = self._api.step(
        step_name,
        [ 'python', self._api.zip.resource('zip.py') ],
        stdin=self._api.json.input(script_input))
    self._api.path.mock_add_paths(self._output)
    return step_result
