import tarfile
from util.gzipwrap import GzipWrap

class TarImageFormatter(object):
  """ Base class for classes which produce a TAR containing image and layer data. """

  def build_stream(self, namespace, repository, tag, synthetic_image_id, layer_json,
                   get_image_iterator, get_layer_iterator):
    """ Builds and streams a synthetic .tar.gz that represents the formatted TAR created by this
        class's implementation.
    """
    return GzipWrap(self.stream_generator(namespace, repository, tag,
                                             synthetic_image_id, layer_json,
                                             get_image_iterator, get_layer_iterator))

  def stream_generator(self, namespace, repository, tag, synthetic_image_id,
                       layer_json, get_image_iterator, get_layer_iterator):
    raise NotImplementedError

  def tar_file(self, name, contents):
    """ Returns the TAR binary representation for a file with the given name and file contents. """
    length = len(contents)
    tar_data = self.tar_file_header(name, length)
    tar_data += contents
    tar_data += self.tar_file_padding(length)
    return tar_data

  def tar_file_padding(self, length):
    """ Returns TAR file padding for file data of the given length. """
    if length % 512 != 0:
      return '\0' * (512 - (length % 512))

    return ''

  def tar_file_header(self, name, file_size):
    """ Returns TAR file header data for a file with the given name and size. """
    info = tarfile.TarInfo(name=name)
    info.type = tarfile.REGTYPE
    info.size = file_size
    return info.tobuf()

  def tar_folder(self, name):
    """ Returns TAR file header data for a folder with the given name. """
    info = tarfile.TarInfo(name=name)
    info.type = tarfile.DIRTYPE
    return info.tobuf()