#!/usr/bin/env python3
# Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
from __future__ import print_function
import os
import sys
import zipfile

# Proguard lookup program classes before library classes. In R8 this is
# not the behaviour (it used to be) R8 will check library classes before
# program classes. Some apps have duplicate classes in the library and program.
# To make these apps work with R8 simulate program classes before library
# classes by creating a new library jar which have all the provided library
# classes which are not also in program classes.
def SanitizeLibrariesInPgconf(
    sanitized_lib_path,
    sanitized_pgconf_path,
    pgconfs,
    injars = None,
    libraryjars = None):
  with open(sanitized_pgconf_path, 'w') as sanitized_pgconf:
    injars = [] if injars is None else injars
    libraryjars = [] if libraryjars is None else libraryjars
    for pgconf in pgconfs:
      pgconf_dirname = os.path.abspath(os.path.dirname(pgconf))
      first_library_jar = True
      with open(pgconf) as pgconf_file:
        for line in pgconf_file:
          trimmed = line.strip()
          if trimmed.startswith('-injars'):
            # Collect -injars and leave them in the configuration.
            injar = os.path.join(
                pgconf_dirname, trimmed[len('-injars'):].strip())
            injars.append(injar)
            sanitized_pgconf.write('-injars {}\n'.format(injar))
          elif trimmed.startswith('-libraryjars'):
            # Collect -libraryjars and replace them with the sanitized library.
            libraryjar = os.path.join(
                pgconf_dirname, trimmed[len('-libraryjars'):].strip())
            libraryjars.append(libraryjar)
            if first_library_jar:
              sanitized_pgconf.write(
                  '-libraryjars {}\n'.format(sanitized_lib_path))
              first_library_jar = False
            sanitized_pgconf.write('# {}'.format(line))
          else:
            sanitized_pgconf.write(line)

  SanitizeLibraries(sanitized_lib_path, libraryjars, injars)


def SanitizeLibraries(sanitized_lib_path, libraryjars, injars):
  program_entries = set()
  library_entries = set()

  for injar in injars:
    with zipfile.ZipFile(injar, 'r') as injar_zf:
      for zipinfo in injar_zf.infolist():
        program_entries.add(zipinfo.filename)

  with zipfile.ZipFile(sanitized_lib_path, 'w') as output_zf:
    for libraryjar in libraryjars:
      with zipfile.ZipFile(libraryjar, 'r') as input_zf:
       for zipinfo in input_zf.infolist():
         if (not zipinfo.filename in program_entries
             and not zipinfo.filename in library_entries):
           library_entries.add(zipinfo.filename)
           output_zf.writestr(zipinfo, input_zf.read(zipinfo))


def usage(argv, error):
  print(error)
  print("Usage: sanitize_libraries.py <sanitized_lib> <sanitized_pgconf> ("
        + "--injar <existing_injar>"
        + "|--libraryjar <existing_library_jar>"
        + "|--pgconf <existing_pgconf>)+")
  return 1


def main(argv):
  if (len(argv) < 4):
    return usage(argv, "Wrong number of arguments!")
  pgconfs = []
  injars = []
  libraryjars = []
  i = 2
  while i < len(argv):
    directive = argv[i]
    if directive not in ['--pgconf', '--injar', '--libraryjar']:
      return usage(
          argv,
          'Unexpected argument, expected one of --pgconf, --injar, and '
              + '--libraryjar.')
    if i + 1 >= len(argv):
      return usage(argv, 'Expected argument after ' + directive + '.')
    file = argv[i + 1]
    if directive == '--pgconf':
      pgconfs.append(file)
    elif directive == '--injar':
      injars.append(file)
    elif directive == '--libraryjar':
      libraryjars.append(file)
    i = i + 2
  SanitizeLibrariesInPgconf(argv[0], argv[1], pgconfs, injars, libraryjars)

if __name__ == '__main__':
  sys.exit(main(sys.argv[1:]))
