#!/usr/bin/python3

# Copyright 2017 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 script to generate Java class to ObjC header mapping for J2ObjC.

This script generates a text file containing mapping between top-level Java
classes to associated ObjC headers, generated by J2ObjC.

The mapping file is used by dependent J2ObjC transpilation actions to locate
the correct header import paths for dependent Java classes.

Inside the script, we read the Java source files and source jars of a single
Java rule, and parse out the package names from the package statements, using
regular expression matching.

Note that we cannot guarantee 100% correctness by using just regular expression,
but it should be good enough. This allows us to avoid doing any further complex
parsing of the source files and keep the script light-weight without other
dependencies. In the future, we can consider implementing a simple Java lexer
here that correctly parses the package statements out of Java files.
"""

import argparse
import os
import re
import zipfile

_PACKAGE_RE = re.compile(r'(package)\s+([\w\.]+);')


def _get_file_map_entry(java_file_path, java_file):
  """Returns the top-level Java class and header file path tuple.

  Args:
    java_file_path: The file path of the source Java file.
    java_file: The actual file of the source java file.
  Returns:
    A tuple containing top-level Java class and associated header file path. Or
    None if no package statement exists in the source file.
  """
  for line in java_file:
    stripped_line = line.strip()
    stripped_line_str = stripped_line
    if isinstance(stripped_line, bytes):
      stripped_line_str = stripped_line.decode('utf-8', 'strict')
    elif not isinstance(stripped_line, (str, bytes)):
      raise TypeError("not expecting type '%s'" % type(stripped_line_str))
    package_statement = _PACKAGE_RE.search(stripped_line_str)

    # We identified a potential package statement.
    if package_statement:
      preceding_characters = stripped_line[0:package_statement.start(1)]
      # We have preceding characters before the package statement. We need to
      # look further into them.
      if preceding_characters:
        # Skip comment line.
        if preceding_characters.startswith('//'):
          continue

        # Preceding characters also must end with a space, represent an end
        # of comment, or end of a statement.
        # Otherwise, we skip the current line.
        if not (preceding_characters[len(preceding_characters) - 1].isspace() or
                preceding_characters.endswith(';') or
                preceding_characters.endswith('*/')):
          continue
      package_name = package_statement.group(2)
      class_name = os.path.splitext(os.path.basename(java_file_path))[0]
      header_file = os.path.splitext(java_file_path)[0] + '.h'
      return (package_name + '.' + class_name, header_file)
  return None


def main():
  parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
  parser.add_argument(
      '--source_files',
      required=False,
      help='The source files')
  parser.add_argument(
      '--source_jars',
      required=False,
      help='The source jars.')
  parser.add_argument(
      '--output_mapping_file',
      required=False,
      help='The output mapping file')

  args, _ = parser.parse_known_args()
  class_to_header_map = dict()

  # Process the source files.
  if args.source_files:
    source_files = args.source_files.split(',')
    for source_file in source_files:
      with open(source_file, 'r') as f:
        entry = _get_file_map_entry(source_file, f)
        if entry:
          class_to_header_map[entry[0]] = entry[1]

  # Process the source jars.
  if args.source_jars:
    source_jars = args.source_jars.split(',')
    for source_jar in source_jars:
      with zipfile.ZipFile(source_jar, 'r') as jar:
        for jar_entry in jar.namelist():
          if jar_entry.endswith('.java'):
            with jar.open(jar_entry) as jar_entry_file:
              entry = _get_file_map_entry(jar_entry, jar_entry_file)
              if entry:
                class_to_header_map[entry[0]] = entry[1]

  # Generate the output header mapping file.
  if args.output_mapping_file:
    with open(args.output_mapping_file, 'w') as output_mapping_file:
      for class_name in sorted(class_to_header_map):
        header_path = class_to_header_map[class_name]
        output_mapping_file.write(class_name + '=' + header_path + '\n')

if __name__ == '__main__':
  main()
