#!/usr/bin/env python3

import sys
import os
import os.path
import re
import subprocess
import tempfile
import urllib.request
import argparse
import hashlib

def initialize_apt(apt_dir, apt_args, args):
  os.mkdir(os.path.join(apt_dir, 'etc'))
  os.mkdir(os.path.join(apt_dir, 'etc', 'apt'))
  os.mkdir(os.path.join(apt_dir, 'etc', 'apt', 'trusted.gpg.d'))
  os.mkdir(os.path.join(apt_dir, 'etc', 'apt', 'preferences.d'))
  os.mkdir(os.path.join(apt_dir, 'var'))
  os.mkdir(os.path.join(apt_dir, 'var', 'lib'))
  os.mkdir(os.path.join(apt_dir, 'var', 'lib', 'dpkg'))
  with open(os.path.join(apt_dir, 'var', 'lib', 'dpkg', 'status'), 'w'):
    pass
  with open(os.path.join(apt_dir, 'etc', 'apt', 'sources.list'), 'w') as f:
    f.write("""
deb http://deb.debian.org/debian/ {release} main contrib non-free
deb-src http://deb.debian.org/debian/ {release} main contrib non-free

deb https://security.debian.org/debian-security {release}-security main contrib non-free
deb-src https://security.debian.org/debian-security {release}-security main contrib non-free

deb http://deb.debian.org/debian/ {release}-updates main contrib non-free
deb-src http://deb.debian.org/debian/ {release}-updates main contrib non-free

deb http://deb.debian.org/debian {release}-backports main contrib non-free
deb-src http://deb.debian.org/debian {release}-backports main contrib non-free
""".format(release=args.release))
  for key in args.apt_key:
    basename = os.path.basename(key)
    urllib.request.urlretrieve(key, os.path.join(apt_dir, 'etc', 'apt', 'trusted.gpg.d', basename))
  subprocess.check_call(["apt-get"] + apt_args + ["update"])

def get_deps(apt_args, package):
  env = dict(os.environ)
  del env['LD_LIBRARY_PATH']
  out = subprocess.check_output(["apt-rdepends"] + apt_args + [package], env=env)
  deps = out.splitlines()
  return set([dep for dep in deps if not dep.startswith(b" ")])

def get_all_deps(apt_args, packages):
  deps = set()
  for package in packages or ():
    deps.update(get_deps(apt_args, package))
  return deps

def map_virtual_packages(packages):
  '''Maps known virtual packages to the preferred concrete packages which
  provide them.'''
  for package in packages:
    if package == b'python-numpy-abi9':
      yield b'python-numpy'
      continue
    if package == b'python3-numpy-abi9':
      yield b'python3-numpy'
      continue
    if package == b'libjack-0.125':
      yield b'libjack-jackd2-0'
      continue
    if package == b'fonts-freefont':
      yield b'fonts-freefont-ttf'
      continue
    if package == b'gsettings-backend':
      yield b'dconf-gsettings-backend'
      continue
    if package == b'gdal-abi-2-4-0':
      yield b'libgdal20'
      continue
    if package == b'libglu1':
      yield b'libglu1-mesa'
      continue
    if package == b'liblapack.so.3':
      yield b'liblapack3'
      continue
    if package == b'libopencl1':
      yield b'ocl-icd-libopencl1'
      continue
    if package == b'libgcc1':
      yield b'libgcc-s1'
      continue
    if package == b'libopencl-1.2-1':
      yield b'ocl-icd-libopencl1'
      continue
    if package == b'libblas.so.3':
      yield b'libblas3'
      continue
    if package == b'debconf-2.0':
      yield b'debconf'
      continue
    yield package

def download_deps(apt_args, packages, excludes, force_includes):
  deps = get_all_deps(apt_args, packages)
  exclude_deps = get_all_deps(apt_args, excludes)
  deps -= exclude_deps
  force_include_deps = get_all_deps(apt_args, force_includes)
  deps |= force_include_deps
  env = dict(os.environ)
  del env['LD_LIBRARY_PATH']
  subprocess.check_call([b"apt-get"] + [a.encode('utf-8') for a in apt_args] + [b"download"] + list(map_virtual_packages(deps)), env=env)

def fixup_files():
  # Gotta remove those pesky epoch numbers in the file names. Bazel doesn't
  # like them.
  regex = re.compile(".%3a")
  contents = os.listdir(os.getcwd())
  for deb in contents:
    new_name = regex.sub("", deb)
    if new_name != deb:
      os.rename(deb, new_name)

def sha256_checksum(filename, block_size=65536):
  sha256 = hashlib.sha256()
  with open(filename, 'rb') as f:
    for block in iter(lambda: f.read(block_size), b''):
      sha256.update(block)
  return sha256.hexdigest()

def print_file_list():
  contents = os.listdir(os.getcwd())
  contents.sort()
  print("_files = {")
  for deb in contents:
    print('  "%s": "%s",' % (deb, sha256_checksum(deb)))
  print("}")

_ALWAYS_EXCLUDE = [
    "dbus-session-bus",
    "debconf",
    "debconf-2.0",
    "default-dbus-session-bus",
    "dpkg",
    "install-info",
    "libc-dev",
    "libc6",
    "libc6-dev",
]

def main(argv):
  parser = argparse.ArgumentParser()
  parser.add_argument("--exclude", "-e", type=str, action="append", help="A package to exclude from the list")
  parser.add_argument("--force-include", type=str, action="append", help="Force include this and its dependencies. Even if listed in excludes.")
  parser.add_argument("--arch", type=str, default="amd64", help="Architecture to download files for.")
  parser.add_argument("--apt-dir", type=str, help=" ".join([
    "File to generate and store apt files in.",
    "Helpful for saving time when downloading multiple groups of packages.",
    "Some flags will be ignored in favor of the values used to create this folder, so be careful.",
    ]))
  parser.add_argument("--release", type=str, default="bullseye", help="Debian release to use.")
  parser.add_argument("--apt-key", type=str, action="append", default=[
    "https://ftp-master.debian.org/keys/archive-key-11.asc",
    "https://ftp-master.debian.org/keys/archive-key-11-security.asc",
  ], help="URL of an additional apt archive key to trust.")
  parser.add_argument("package", nargs="+", help="The packages to download.")
  args = parser.parse_args(argv[1:])
  if args.apt_dir:
    apt_dir = args.apt_dir
  else:
    apt_dir = tempfile.mkdtemp()
  apt_args = ["-o", "Dir=" + apt_dir, "-o", "APT::Architecture=" + args.arch]
  if not args.apt_dir:
    print("Creating apt files in %s" % apt_dir)
    initialize_apt(apt_dir, apt_args, args)
  folder = tempfile.mkdtemp()
  os.chdir(folder)
  excludes = args.exclude or []
  # Exclude common packages that don't make sense to include in everything all
  # the time.
  excludes += _ALWAYS_EXCLUDE
  download_deps(apt_args, args.package, excludes, args.force_include)
  fixup_files()
  print_file_list()
  print("Your packages are all in %s" % folder)

if __name__ == "__main__":
  sys.exit(main(sys.argv))
