# Copyright 2015 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""A simple cross-platform helper to create a debian package."""

import gzip
import hashlib
import os.path
from StringIO import StringIO
import sys
import tarfile
import textwrap
import time

from third_party.py import gflags

# list of debian fields : (name, mandatory, wrap[, default])
# see http://www.debian.org/doc/debian-policy/ch-controlfields.html
DEBIAN_FIELDS = [
    ('Package', True, False),
    ('Version', True, False),
    ('Section', False, False, 'contrib/devel'),
    ('Priority', False, False, 'optional'),
    ('Architecture', True, False, 'all'),
    ('Depends', False, True, []),
    ('Recommends', False, True, []),
    ('Suggests', False, True, []),
    ('Enhances', False, True, []),
    ('Conflicts', False, True, []),
    ('Pre-Depends', False, True, []),
    ('Installed-Size', False, False),
    ('Maintainer', True, False),
    ('Description', True, True),
    ('Homepage', False, False),
    ('Built-Using', False, False, 'Bazel'),
    ('Distribution', False, False, 'unstable'),
    ('Urgency', False, False, 'medium'),
]

gflags.DEFINE_string('output', None, 'The output file, mandatory')
gflags.MarkFlagAsRequired('output')

gflags.DEFINE_string('changes', None, 'The changes output file, mandatory.')
gflags.MarkFlagAsRequired('changes')

gflags.DEFINE_string('data', None,
                     'Path to the data tarball, mandatory')
gflags.MarkFlagAsRequired('data')

gflags.DEFINE_string('preinst', None,
                     'The preinst script (prefix with @ to provide a path).')
gflags.DEFINE_string('postinst', None,
                     'The postinst script (prefix with @ to provide a path).')
gflags.DEFINE_string('prerm', None,
                     'The prerm script (prefix with @ to provide a path).')
gflags.DEFINE_string('postrm', None,
                     'The postrm script (prefix with @ to provide a path).')


# see
# https://www.debian.org/doc/manuals/debian-faq/ch-pkg_basics.en.html#s-conffile
gflags.DEFINE_multistring(
    'conffile', None,
    'List of conffiles (prefix item with @ to provide a path)')


def MakeGflags():
  for field in DEBIAN_FIELDS:
    fieldname = field[0].replace('-', '_').lower()
    msg = 'The value for the %s content header entry.' % field[0]
    if len(field) > 3:
      if type(field[3]) is list:
        gflags.DEFINE_multistring(fieldname, field[3], msg)
      else:
        gflags.DEFINE_string(fieldname, field[3], msg)
    else:
      gflags.DEFINE_string(fieldname, None, msg)
    if field[1]:
      gflags.MarkFlagAsRequired(fieldname)


def AddArFileEntry(fileobj, filename,
                   content='', timestamp=0,
                   owner_id=0, group_id=0, mode=0o644):
  """Add a AR file entry to fileobj."""
  fileobj.write((filename + '/').ljust(16))    # filename (SysV)
  fileobj.write(str(timestamp).ljust(12))      # timestamp
  fileobj.write(str(owner_id).ljust(6))        # owner id
  fileobj.write(str(group_id).ljust(6))        # group id
  fileobj.write(oct(mode).ljust(8))            # mode
  fileobj.write(str(len(content)).ljust(10))   # size
  fileobj.write('\x60\x0a')                    # end of file entry
  fileobj.write(content)
  if len(content) % 2 != 0:
    fileobj.write('\n')  # 2-byte alignment padding


def MakeDebianControlField(name, value, wrap=False):
  """Add a field to a debian control file."""
  result = name + ': '
  if type(value) is list:
    value = ', '.join(value)
  if wrap:
    result += ' '.join(value.split('\n'))
    result = textwrap.fill(result,
                           break_on_hyphens=False,
                           break_long_words=False)
  else:
    result += value
  return result.replace('\n', '\n ') + '\n'


def CreateDebControl(extrafiles=None, **kwargs):
  """Create the control.tar.gz file."""
  # create the control file
  controlfile = ''
  for values in DEBIAN_FIELDS:
    fieldname = values[0]
    key = fieldname[0].lower() + fieldname[1:].replace('-', '')
    if values[1] or (key in kwargs and kwargs[key]):
      controlfile += MakeDebianControlField(fieldname, kwargs[key], values[2])
  # Create the control.tar file
  tar = StringIO()
  with gzip.GzipFile('control.tar.gz', mode='w', fileobj=tar, mtime=0) as gz:
    with tarfile.open('control.tar.gz', mode='w', fileobj=gz) as f:
      tarinfo = tarfile.TarInfo('control')
      tarinfo.size = len(controlfile)
      f.addfile(tarinfo, fileobj=StringIO(controlfile))
      if extrafiles:
        for name, (data, mode) in extrafiles.iteritems():
          tarinfo = tarfile.TarInfo(name)
          tarinfo.size = len(data)
          tarinfo.mode = mode
          f.addfile(tarinfo, fileobj=StringIO(data))
  control = tar.getvalue()
  tar.close()
  return control


def CreateDeb(output,
              data,
              preinst=None,
              postinst=None,
              prerm=None,
              postrm=None,
              conffiles=None,
              **kwargs):
  """Create a full debian package."""
  extrafiles = {}
  if preinst:
    extrafiles['preinst'] = (preinst, 0o755)
  if postinst:
    extrafiles['postinst'] = (postinst, 0o755)
  if prerm:
    extrafiles['prerm'] = (prerm, 0o755)
  if postrm:
    extrafiles['postrm'] = (postrm, 0o755)
  if conffiles:
    extrafiles['conffiles'] = ('\n'.join(conffiles), 0o644)
  control = CreateDebControl(extrafiles=extrafiles, **kwargs)

  # Write the final AR archive (the deb package)
  with open(output, 'w') as f:
    f.write('!<arch>\n')  # Magic AR header
    AddArFileEntry(f, 'debian-binary', '2.0\n')
    AddArFileEntry(f, 'control.tar.gz', control)
    # Tries to preserve the extension name
    ext = os.path.basename(data).split('.')[-2:]
    if len(ext) < 2:
      ext = 'tar'
    elif ext[1] == 'tgz':
      ext = 'tar.gz'
    elif ext[1] == 'tar.bzip2':
      ext = 'tar.bz2'
    else:
      ext = '.'.join(ext)
      if ext not in ['tar.bz2', 'tar.gz', 'tar.xz', 'tar.lzma']:
        ext = 'tar'
    with open(data, 'r') as datafile:
      data = datafile.read()
    AddArFileEntry(f, 'data.' + ext, data)


def GetChecksumsFromFile(filename, hash_fns=None):
  """Computes MD5 and/or other checksums of a file.

  Args:
    filename: Name of the file.
    hash_fns: Mapping of hash functions.
              Default is {'md5': hashlib.md5}

  Returns:
    Mapping of hash names to hexdigest strings.
    { <hashname>: <hexdigest>, ... }
  """
  hash_fns = hash_fns or {'md5': hashlib.md5}
  checksums = {k: fn() for (k, fn) in hash_fns.items()}

  with open(filename) as file_handle:
    while True:
      buf = file_handle.read(1048576)  # 1 MiB
      if not buf:
        break
      for hashfn in checksums.values():
        hashfn.update(buf)

  return {k: fn.hexdigest() for (k, fn) in checksums.items()}


def CreateChanges(output,
                  deb_file,
                  architecture,
                  short_description,
                  maintainer,
                  package,
                  version,
                  section,
                  priority,
                  distribution,
                  urgency,
                  timestamp=0):
  """Create the changes file."""
  checksums = GetChecksumsFromFile(deb_file, {'md5': hashlib.md5,
                                              'sha1': hashlib.sha1,
                                              'sha256': hashlib.sha256})
  debsize = str(os.path.getsize(deb_file))
  deb_basename = os.path.basename(deb_file)

  changesdata = ''.join(
      MakeDebianControlField(*x)
      for x in [('Format', '1.8'), ('Date', time.ctime(timestamp)), (
          'Source', package
      ), ('Binary', package
         ), ('Architecture', architecture), ('Version', version), (
             'Distribution', distribution
         ), ('Urgency', urgency), ('Maintainer', maintainer), (
             'Changed-By', maintainer
         ), ('Description', '\n%s - %s' % (package, short_description)
            ), ('Changes', ('\n%s (%s) %s; urgency=%s'
                            '\nChanges are tracked in revision control.'
                           ) % (package, version, distribution, urgency)
               ), ('Files', '\n' + ' '.join(
                   [checksums['md5'], debsize, section, priority, deb_basename])
                  ), ('Checksums-Sha1', '\n' + ' '.join(
                      [checksums['sha1'], debsize, deb_basename])
                     ), ('Checksums-Sha256', '\n' + ' '.join(
                         [checksums['sha256'], debsize, deb_basename]))])
  with open(output, 'w') as changes_fh:
    changes_fh.write(changesdata)


def GetFlagValue(flagvalue, strip=True):
  if flagvalue:
    if flagvalue[0] == '@':
      with open(flagvalue[1:], 'r') as f:
        flagvalue = f.read()
    if strip:
      return flagvalue.strip()
  return flagvalue


def GetFlagValues(flagvalues):
  if flagvalues:
    return [GetFlagValue(f, False) for f in flagvalues]
  else:
    return None


def main(unused_argv):
  CreateDeb(
      FLAGS.output,
      FLAGS.data,
      preinst=GetFlagValue(FLAGS.preinst, False),
      postinst=GetFlagValue(FLAGS.postinst, False),
      prerm=GetFlagValue(FLAGS.prerm, False),
      postrm=GetFlagValue(FLAGS.postrm, False),
      conffiles=GetFlagValues(FLAGS.conffile),
      package=FLAGS.package,
      version=GetFlagValue(FLAGS.version),
      description=GetFlagValue(FLAGS.description),
      maintainer=FLAGS.maintainer,
      section=FLAGS.section,
      architecture=FLAGS.architecture,
      depends=FLAGS.depends,
      suggests=FLAGS.suggests,
      enhances=FLAGS.enhances,
      preDepends=FLAGS.pre_depends,
      recommends=FLAGS.recommends,
      homepage=FLAGS.homepage,
      builtUsing=GetFlagValue(FLAGS.built_using),
      priority=FLAGS.priority,
      conflicts=FLAGS.conflicts,
      installedSize=GetFlagValue(FLAGS.installed_size))
  CreateChanges(
      output=FLAGS.changes,
      deb_file=FLAGS.output,
      architecture=FLAGS.architecture,
      short_description=GetFlagValue(FLAGS.description).split('\n')[0],
      maintainer=FLAGS.maintainer, package=FLAGS.package,
      version=GetFlagValue(FLAGS.version), section=FLAGS.section,
      priority=FLAGS.priority, distribution=FLAGS.distribution,
      urgency=FLAGS.urgency)

if __name__ == '__main__':
  MakeGflags()
  FLAGS = gflags.FLAGS
  main(FLAGS(sys.argv))
