#!/usr/bin/python2.7

# 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()
    package_statement = _PACKAGE_RE.search(stripped_line)

    # 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()
