#!/usr/bin/env python
#
# Copyright 2016 Google Inc.
#
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.


"""Utilities for zipping and unzipping files."""


import fnmatch
import ntpath
import os
import posixpath
import zipfile


def filtered(names, to_skip):
  """Filter the list of file or directory names."""
  rv = names[:]
  for pattern in to_skip:
    rv = [n for n in rv if not fnmatch.fnmatch(n, pattern)]
  return rv


def zip(target_dir, zip_file, to_skip=None):  # pylint: disable=W0622
  """Zip the given directory, write to the given zip file."""
  if not os.path.isdir(target_dir):
    raise IOError('%s does not exist!' % target_dir)
  to_skip = to_skip or []
  with zipfile.ZipFile(zip_file, 'w', zipfile.ZIP_DEFLATED, True) as z:
    for r, d, f in os.walk(target_dir, topdown=True):
      d[:] = filtered(d, to_skip)
      for filename in filtered(f, to_skip):
        filepath = os.path.join(r, filename)
        zi = zipfile.ZipInfo(filepath)
        zi.filename = os.path.relpath(filepath, target_dir)
        if os.name == 'nt':
          # Dumb path separator replacement for Windows.
          zi.filename = zi.filename.replace(ntpath.sep, posixpath.sep)
        try:
          perms = os.stat(filepath).st_mode
        except OSError:
          if os.path.islink(filepath):
            print 'Skipping symlink %s' % filepath
            continue
          else:
            raise
        zi.external_attr = perms << 16L
        zi.compress_type = zipfile.ZIP_DEFLATED
        with open(filepath, 'rb') as f:
          content = f.read()
        z.writestr(zi, content)
      for dirname in d:
        dirpath = os.path.join(r, dirname)
        z.write(dirpath, os.path.relpath(dirpath, target_dir))


def unzip(zip_file, target_dir):
  """Unzip the given zip file into the target dir."""
  if not os.path.isdir(target_dir):
    os.makedirs(target_dir)
  with zipfile.ZipFile(zip_file, 'r', zipfile.ZIP_DEFLATED, True) as z:
    for zi in z.infolist():
      dst_subpath = zi.filename
      if os.name == 'nt':
        # Dumb path separator replacement for Windows.
        dst_subpath = dst_subpath.replace(posixpath.sep, ntpath.sep)
      dst_path = os.path.join(target_dir, dst_subpath)
      if dst_path.endswith(os.path.sep):
        os.mkdir(dst_path)
      else:
        with open(dst_path, 'wb') as f:
          f.write(z.read(zi))
      perms = zi.external_attr >> 16L
      os.chmod(dst_path, perms)
