#!/usr/bin/python2.7

# 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 wrapper script for J2ObjC transpiler.

This script wraps around J2ObjC transpiler to also output a dependency mapping
file by scanning the import and include directives of the J2ObjC-translated
files.
"""

import argparse
import errno
import multiprocessing
import os
import Queue
import re
import shutil
import subprocess
import tempfile
import threading
import zipfile

_INCLUDE_RE = re.compile('#(include|import) "([^"]+)"')
_CONST_DATE_TIME = [1980, 1, 1, 0, 0, 0]


def RunJ2ObjC(java, jvm_flags, j2objc, main_class, output_file_path,
              j2objc_args, source_paths, files_to_translate):
  """Runs J2ObjC transpiler to translate Java source files to ObjC.

  Args:
    java: The path of the Java executable.
    jvm_flags: A comma-separated list of flags to pass to JVM.
    j2objc: The deploy jar of J2ObjC.
    main_class: The J2ObjC main class to invoke.
    output_file_path: The output file directory.
    j2objc_args: A list of args to pass to J2ObjC transpiler.
    source_paths: A list of directories that contain sources to translate.
    files_to_translate: A list of relative paths (relative to source_paths) that
        point to sources to translate.
  Returns:
    None.
  """
  source_file_manifest_content = ' '.join(files_to_translate)
  fd = None
  param_filename = None
  try:
    fd, param_filename = tempfile.mkstemp(text=True)
    os.write(fd, source_file_manifest_content)
  finally:
    if fd:
      os.close(fd)
  try:
    j2objc_cmd = [java]
    j2objc_cmd.extend(filter(None, jvm_flags.split(',')))
    j2objc_cmd.extend(['-cp', j2objc, main_class])
    j2objc_cmd.extend(j2objc_args)
    j2objc_cmd.extend(['-sourcepath', ':'.join(source_paths)])
    j2objc_cmd.extend(['-d', output_file_path])
    j2objc_cmd.extend(['@%s' % param_filename])
    subprocess.check_call(j2objc_cmd, stderr=subprocess.STDOUT)
  finally:
    if param_filename:
      os.remove(param_filename)


def WriteDepMappingFile(objc_files,
                        objc_file_root,
                        output_dependency_mapping_file,
                        file_open=open):
  """Scans J2ObjC-translated files and outputs a dependency mapping file.

  The mapping file contains mappings between translated source files and their
  imported source files scanned from the import and include directives.

  Args:
    objc_files: A list of ObjC files translated by J2ObjC.
    objc_file_root: The file path which represents a directory where the
        generated ObjC files reside.
    output_dependency_mapping_file: The path of the dependency mapping file to
        write to.
    file_open: Reference to the builtin open function so it may be
        overridden for testing.
  Raises:
    RuntimeError: If spawned threads throw errors during processing.
  Returns:
    None.
  """
  dep_mapping = dict()
  input_file_queue = Queue.Queue()
  output_dep_mapping_queue = Queue.Queue()
  error_message_queue = Queue.Queue()
  for objc_file in objc_files:
    input_file_queue.put(os.path.join(objc_file_root, objc_file))

  for _ in xrange(multiprocessing.cpu_count()):
    t = threading.Thread(target=_ReadDepMapping, args=(input_file_queue,
                                                       output_dep_mapping_queue,
                                                       error_message_queue,
                                                       objc_file_root,
                                                       file_open))
    t.start()

  input_file_queue.join()

  if not error_message_queue.empty():
    error_messages = [error_message for error_message in
                      error_message_queue.queue]
    raise RuntimeError('\n'.join(error_messages))

  while not output_dep_mapping_queue.empty():
    entry_file, deps = output_dep_mapping_queue.get()
    dep_mapping[entry_file] = deps

  f = file_open(output_dependency_mapping_file, 'w')
  for entry in sorted(dep_mapping):
    for dep in dep_mapping[entry]:
      f.write(entry + ':' + dep + '\n')
  f.close()


def _ReadDepMapping(input_file_queue, output_dep_mapping_queue,
                    error_message_queue, output_root, file_open=open):
  while True:
    try:
      input_file = input_file_queue.get_nowait()
    except Queue.Empty:
      # No more work left in the queue.
      return

    try:
      deps = []
      entry = os.path.relpath(os.path.splitext(input_file)[0], output_root)
      with file_open(input_file, 'r') as f:
        for line in f:
          include = _INCLUDE_RE.match(line)
          if include:
            include_path = include.group(2)
            dep = os.path.splitext(include_path)[0]
            if dep != entry:
              deps.append(dep)
      output_dep_mapping_queue.put((entry, deps))
    except Exception as e:  # pylint: disable=broad-except
      error_message_queue.put(str(e))
    finally:
      # We need to mark the task done to prevent blocking the main process
      # indefinitely.
      input_file_queue.task_done()


def WriteArchiveSourceMappingFile(compiled_archive_file_path,
                                  output_archive_source_mapping_file,
                                  objc_files,
                                  file_open=open):
  """Writes a mapping file between archive file to associated ObjC source files.

  Args:
    compiled_archive_file_path: The path of the archive file.
    output_archive_source_mapping_file: A path of the mapping file to write to.
    objc_files: A list of ObjC files translated by J2ObjC.
    file_open: Reference to the builtin open function so it may be
        overridden for testing.
  Returns:
    None.
  """
  with file_open(output_archive_source_mapping_file, 'w') as f:
    for objc_file in objc_files:
      f.write(compiled_archive_file_path + ':' + objc_file + '\n')


def _ParseArgs(j2objc_args):
  """Separate arguments passed to J2ObjC into source files and J2ObjC flags.

  Args:
    j2objc_args: A list of args to pass to J2ObjC transpiler.
  Returns:
    A tuple containing source files and J2ObjC flags
  """
  source_files = []
  flags = []
  is_next_flag_value = False
  for j2objc_arg in j2objc_args:
    if j2objc_arg.startswith('-'):
      flags.append(j2objc_arg)
      is_next_flag_value = True
    elif is_next_flag_value:
      flags.append(j2objc_arg)
      is_next_flag_value = False
    else:
      source_files.append(j2objc_arg)
  return (source_files, flags)


def _J2ObjcOutputObjcFiles(java_files):
  """Returns the relative paths of the associated output ObjC source files.

  Args:
    java_files: The list of Java files to translate.
  Returns:
    A list of associated output ObjC source files.
  """
  return [os.path.splitext(java_file)[0] + '.m' for java_file in java_files]


def UnzipGenJarSources(gen_src_jar):
  """Unzips the gen srcjar containing outputs from Java annotation processors.

  Args:
    gen_src_jar: The path of the gen srcjar.
  Returns:
    A tuple of the temporary output root and a list of root-relative paths of
    unzipped Java files
  """
  genjar_java_files = []
  if gen_src_jar:
    tmp_input_root = tempfile.mkdtemp()
    zip_ref = zipfile.ZipFile(gen_src_jar, 'r')

    for file_entry in zip_ref.namelist():
      # We only care about Java source files.
      if file_entry.endswith('.java'):
        genjar_java_files.append(file_entry)

    zip_ref.extractall(tmp_input_root, genjar_java_files)
    zip_ref.close()
    return (tmp_input_root, genjar_java_files)
  else:
    return None


def RenameGenJarObjcFileRootInFileContent(tmp_objc_file_root,
                                          j2objc_source_paths,
                                          gen_src_jar, genjar_objc_files,
                                          execute=subprocess.check_call):
  """Renames references to temporary root inside ObjC sources from gen srcjar.

  Args:
    tmp_objc_file_root: The temporary output root containing ObjC sources.
    j2objc_source_paths: The source paths used by J2ObjC.
    gen_src_jar: The path of the gen srcjar.
    genjar_objc_files: The list of ObjC sources translated from the gen srcjar.
    execute: The function used to execute shell commands.
  Returns:
    None.
  """
  if genjar_objc_files:
    abs_genjar_objc_source_files = [
        os.path.join(tmp_objc_file_root, genjar_objc_file)
        for genjar_objc_file in genjar_objc_files
    ]
    abs_genjar_objc_header_files = [
        os.path.join(tmp_objc_file_root,
                     os.path.splitext(genjar_objc_file)[0] + '.h')
        for genjar_objc_file in genjar_objc_files
    ]

    # We execute a command to change all references of the temporary Java root
    # where we unzipped the gen srcjar sources, to the actual gen srcjar that
    # contains the original Java sources.
    cmd = [
        'sed',
        '-i',
        '-e',
        's|%s/|%s::|g' % (j2objc_source_paths[1], gen_src_jar)
    ]
    cmd.extend(abs_genjar_objc_source_files)
    cmd.extend(abs_genjar_objc_header_files)
    execute(cmd, stderr=subprocess.STDOUT)


def MoveObjcFileToFinalOutputRoot(objc_files,
                                  tmp_objc_file_root,
                                  final_objc_file_root,
                                  suffix,
                                  os_module=os,
                                  shutil_module=shutil):
  """Moves ObjC files from temporary location to the final output location.

  Args:
    objc_files: The list of objc files to move.
    tmp_objc_file_root: The temporary output root containing ObjC sources.
    final_objc_file_root: The final output root.
    suffix: The suffix of the files to move.
    os_module: The os python module.
    shutil_module: The shutil python module.
  Returns:
    None.
  """
  for objc_file in objc_files:
    file_with_suffix = os_module.path.splitext(objc_file)[0] + suffix
    dest_path = os_module.path.join(
        final_objc_file_root, file_with_suffix)
    dest_path_dir = os_module.path.dirname(dest_path)

    if not os_module.path.isdir(dest_path_dir):
      try:
        os_module.makedirs(dest_path_dir)
      except OSError as e:
        if e.errno != errno.EEXIST or not os_module.path.isdir(dest_path_dir):
          raise

    shutil_module.move(
        os_module.path.join(tmp_objc_file_root, file_with_suffix),
        dest_path)


def PostJ2ObjcFileProcessing(normal_objc_files, genjar_objc_files,
                             tmp_objc_file_root, final_objc_file_root,
                             j2objc_source_paths, gen_src_jar,
                             output_gen_source_dir, output_gen_header_dir):
  """Performs cleanups on ObjC files and moves them to final output location.

  Args:
    normal_objc_files: The list of objc files translated from normal Java files.
    genjar_objc_files: The list of ObjC sources translated from the gen srcjar.
    tmp_objc_file_root: The temporary output root containing ObjC sources.
    final_objc_file_root: The final output root.
    j2objc_source_paths: The source paths used by J2ObjC.
    gen_src_jar: The path of the gen srcjar.
    output_gen_source_dir: The final output directory of ObjC source files
        translated from gen srcjar. Maybe null.
    output_gen_header_dir: The final output directory of ObjC header files
        translated from gen srcjar. Maybe null.
  Returns:
    None.
  """
  RenameGenJarObjcFileRootInFileContent(tmp_objc_file_root,
                                        j2objc_source_paths,
                                        gen_src_jar,
                                        genjar_objc_files)
  MoveObjcFileToFinalOutputRoot(normal_objc_files,
                                tmp_objc_file_root,
                                final_objc_file_root,
                                '.m')
  MoveObjcFileToFinalOutputRoot(normal_objc_files,
                                tmp_objc_file_root,
                                final_objc_file_root,
                                '.h')

  if output_gen_source_dir:
    MoveObjcFileToFinalOutputRoot(
        genjar_objc_files,
        tmp_objc_file_root,
        output_gen_source_dir,
        '.m')

  if output_gen_header_dir:
    MoveObjcFileToFinalOutputRoot(
        genjar_objc_files,
        tmp_objc_file_root,
        output_gen_header_dir,
        '.h')


def GenerateJ2objcMappingFiles(normal_objc_files,
                               genjar_objc_files,
                               tmp_objc_file_root,
                               output_dependency_mapping_file,
                               output_archive_source_mapping_file,
                               compiled_archive_file_path):
  """Generates J2ObjC mapping files.

  Args:
    normal_objc_files: The list of objc files translated from normal Java files.
    genjar_objc_files: The list of ObjC sources translated from the gen srcjar.
    tmp_objc_file_root: The temporary output root containing ObjC sources.
    output_dependency_mapping_file: The path of the dependency mapping file to
        write to.
    output_archive_source_mapping_file: A path of the mapping file to write to.
    compiled_archive_file_path: The path of the archive file.
  Returns:
    None.
  """
  WriteDepMappingFile(normal_objc_files + genjar_objc_files,
                      tmp_objc_file_root,
                      output_dependency_mapping_file)

  if output_archive_source_mapping_file:
    WriteArchiveSourceMappingFile(compiled_archive_file_path,
                                  output_archive_source_mapping_file,
                                  normal_objc_files + genjar_objc_files)


def main():
  parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
  parser.add_argument(
      '--java',
      required=True,
      help='The path to the Java executable.')
  parser.add_argument(
      '--jvm_flags',
      default='-Xss4m',
      help='A comma-separated list of flags to pass to the JVM.')
  parser.add_argument(
      '--j2objc',
      required=True,
      help='The path to the J2ObjC deploy jar.')
  parser.add_argument(
      '--main_class',
      required=True,
      help='The main class of the J2ObjC deploy jar to execute.')
  # TODO(rduan): Remove, no longer needed.
  parser.add_argument(
      '--translated_source_files',
      required=False,
      help=('A comma-separated list of file paths where J2ObjC will write the '
            'translated files to.'))
  parser.add_argument(
      '--output_dependency_mapping_file',
      required=True,
      help='The file path of the dependency mapping file to write to.')
  parser.add_argument(
      '--objc_file_path', '-d',
      required=True,
      help=('The file path which represents a directory where the generated '
            'ObjC files reside.'))
  parser.add_argument(
      '--output_archive_source_mapping_file',
      help='The file path of the mapping file containing mappings between the '
           'translated source files and the to-be-generated archive file '
           'compiled from those source files. --compile_archive_file_path must '
           'be specified if this option is specified.')
  parser.add_argument(
      '--compiled_archive_file_path',
      required=False,
      help=('The archive file path that will be produced by ObjC compile action'
            ' later'))
  parser.add_argument(
      '--gen_src_jar',
      required=False,
      help='The jar containing Java sources generated by annotation processor.')
  parser.add_argument(
      '--output_gen_source_dir',
      required=False,
      help='The output directory of ObjC source files translated from the gen'
           ' srcjar')
  parser.add_argument(
      '--output_gen_header_dir',
      required=False,
      help='The output directory of ObjC header files translated from the gen'
           ' srcjar')

  args, pass_through_args = parser.parse_known_args()
  normal_java_files, j2objc_flags = _ParseArgs(pass_through_args)
  genjar_java_files = []
  j2objc_source_paths = [os.getcwd()]

  # Unzip the gen jar, so J2ObjC can translate the contained sources.
  # Also add the temporary directory containing the unzipped sources as a source
  # path for J2ObjC, so it can find these sources.
  genjar_source_tuple = UnzipGenJarSources(args.gen_src_jar)
  if genjar_source_tuple:
    j2objc_source_paths.append(genjar_source_tuple[0])
    genjar_java_files = genjar_source_tuple[1]

  # Run J2ObjC over the normal input Java files and unzipped gen jar Java files.
  # The output is stored in a temporary directory.
  tmp_objc_file_root = tempfile.mkdtemp()
  RunJ2ObjC(args.java,
            args.jvm_flags,
            args.j2objc,
            args.main_class,
            tmp_objc_file_root,
            j2objc_flags,
            j2objc_source_paths,
            normal_java_files + genjar_java_files)

  # Calculate the relative paths of generated objc files.
  normal_objc_files = _J2ObjcOutputObjcFiles(normal_java_files)
  genjar_objc_files = _J2ObjcOutputObjcFiles(genjar_java_files)

  # Generate J2ObjC mapping files needed for distributed builds.
  GenerateJ2objcMappingFiles(normal_objc_files,
                             genjar_objc_files,
                             tmp_objc_file_root,
                             args.output_dependency_mapping_file,
                             args.output_archive_source_mapping_file,
                             args.compiled_archive_file_path)

  # Post J2ObjC-run processing, involving file editing, zipping and moving
  # files to their final output locations.
  PostJ2ObjcFileProcessing(
      normal_objc_files,
      genjar_objc_files,
      tmp_objc_file_root,
      args.objc_file_path,
      j2objc_source_paths,
      args.gen_src_jar,
      args.output_gen_source_dir,
      args.output_gen_header_dir)

if __name__ == '__main__':
  main()
