#!/usr/bin/env python3
#
# Copyright 2023 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import argparse
import logging
import os
import shutil
import sys
import time

import compile_java

from util import build_utils
import action_helpers  # build_utils adds //build to sys.path.


def _RunCompiler(args,
                 kotlinc_cmd,
                 source_files,
                 jar_path,
                 intermediates_out_dir=None):
  """Runs the Kotlin compiler."""
  logging.info('Starting _RunCompiler')

  source_files = source_files.copy()
  kt_files = [f for f in source_files if f.endswith('.kt')]
  assert len(kt_files) > 0, 'At least one .kt file must be passed in.'

  java_srcjars = args.java_srcjars

  # Use jar_path's directory to ensure paths are relative (needed for goma).
  temp_dir = jar_path + '.staging'
  build_utils.DeleteDirectory(temp_dir)
  os.makedirs(temp_dir)
  try:
    classes_dir = os.path.join(temp_dir, 'classes')
    os.makedirs(classes_dir)

    input_srcjars_dir = os.path.join(intermediates_out_dir or temp_dir,
                                     'input_srcjars')

    if java_srcjars:
      logging.info('Extracting srcjars to %s', input_srcjars_dir)
      build_utils.MakeDirectory(input_srcjars_dir)
      for srcjar in args.java_srcjars:
        source_files += build_utils.ExtractAll(srcjar,
                                               no_clobber=True,
                                               path=input_srcjars_dir,
                                               pattern='*.java')
      logging.info('Done extracting srcjars')

    # Don't include the output directory in the initial set of args since it
    # being in a temp dir makes it unstable (breaks md5 stamping).
    cmd = list(kotlinc_cmd)
    cmd += ['-d', classes_dir]

    if args.classpath:
      cmd += ['-classpath', ':'.join(args.classpath)]

    # This a kotlinc plugin to generate header files for .kt files, similar to
    # turbine for .java files.
    jvm_abi_path = os.path.join(build_utils.KOTLIN_HOME, 'lib',
                                'jvm-abi-gen.jar')
    cmd += [
        f'-Xplugin={jvm_abi_path}', '-P',
        'plugin:org.jetbrains.kotlin.jvm.abi:outputDir=' +
        args.interface_jar_path
    ]

    # Pass source paths as response files to avoid extremely long command
    # lines that are tedius to debug.
    source_files_rsp_path = os.path.join(temp_dir, 'files_list.txt')
    with open(source_files_rsp_path, 'w') as f:
      f.write(' '.join(source_files))
    cmd += ['@' + source_files_rsp_path]

    # Explicitly set JAVA_HOME since some bots do not have this already set.
    env = os.environ.copy()
    env['JAVA_HOME'] = build_utils.JAVA_HOME

    logging.debug('Build command %s', cmd)
    start = time.time()
    build_utils.CheckOutput(cmd,
                            env=env,
                            print_stdout=args.chromium_code,
                            fail_on_output=args.warnings_as_errors)
    logging.info('Kotlin compilation took %ss', time.time() - start)

    compile_java.CreateJarFile(jar_path, classes_dir)

    logging.info('Completed all steps in _RunCompiler')
  finally:
    shutil.rmtree(temp_dir)


def _ParseOptions(argv):
  parser = argparse.ArgumentParser()
  action_helpers.add_depfile_arg(parser)

  parser.add_argument('--java-srcjars',
                      action='append',
                      default=[],
                      help='List of srcjars to include in compilation.')
  parser.add_argument(
      '--generated-dir',
      help='Subdirectory within target_gen_dir to place extracted srcjars and '
      'annotation processor output for codesearch to find.')
  parser.add_argument('--classpath', action='append', help='Classpath to use.')
  parser.add_argument(
      '--chromium-code',
      action='store_true',
      help='Whether code being compiled should be built with stricter '
      'warnings for chromium code.')
  parser.add_argument('--gomacc-path',
                      help='When set, prefix kotlinc command with gomacc')
  parser.add_argument('--warnings-as-errors',
                      action='store_true',
                      help='Treat all warnings as errors.')
  parser.add_argument('--jar-path', help='Jar output path.', required=True)
  parser.add_argument('--interface-jar-path',
                      help='Interface jar output path.',
                      required=True)

  args, extra_args = parser.parse_known_args(argv)

  args.classpath = action_helpers.parse_gn_list(args.classpath)
  args.java_srcjars = action_helpers.parse_gn_list(args.java_srcjars)

  source_files = []
  for arg in extra_args:
    # Interpret a path prefixed with @ as a file containing a list of sources.
    if arg.startswith('@'):
      source_files.extend(build_utils.ReadSourcesList(arg[1:]))
    else:
      assert not arg.startswith('--'), f'Undefined option {arg}'
      source_files.append(arg)

  return args, source_files


def main(argv):
  build_utils.InitLogging('KOTLINC_DEBUG')
  argv = build_utils.ExpandFileArgs(argv)
  args, source_files = _ParseOptions(argv)

  kotlinc_cmd = []
  if args.gomacc_path:
    kotlinc_cmd.append(args.gomacc_path)
  kotlinc_cmd.append(build_utils.KOTLINC_PATH)

  kotlinc_cmd += [
      '-no-jdk',  # Avoid depending on the bundled JDK.
      # Avoid depending on the bundled Kotlin stdlib. This may have a version
      # skew with the one in //third_party/android_deps (which is the one we
      # prefer to use).
      '-no-stdlib',
      # Avoid depending on the bundled Kotlin reflect libs.
      '-no-reflect',
  ]

  if args.generated_dir:
    # Delete any stale files in the generated directory. The purpose of
    # args.generated_dir is for codesearch.
    shutil.rmtree(args.generated_dir, True)

  _RunCompiler(args,
               kotlinc_cmd,
               source_files,
               args.jar_path,
               intermediates_out_dir=args.generated_dir)

  if args.depfile:
    # GN already knows of the source files, so avoid listing individual files
    # in the depfile.
    action_helpers.write_depfile(args.depfile, args.jar_path, args.classpath)


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