#!/usr/bin/env python3
#
# Copyright (C) 2021 The Android Open Source Project
#
# 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.

"""
This scripts compiles Java files which are needed to execute run-tests.
It is intended to be used only from soong genrule.
"""

import argparse
import functools
import glob
import os
import pathlib
import re
import shlex
import shutil
import subprocess
import sys
import zipfile

from argparse import ArgumentParser
from concurrent.futures import ThreadPoolExecutor
from fcntl import lockf, LOCK_EX, LOCK_NB
from importlib.machinery import SourceFileLoader
from os import environ, getcwd, chdir, cpu_count, chmod
from os.path import relpath
from pathlib import Path
from pprint import pprint
from re import match
from shutil import copytree, rmtree
from subprocess import run
from tempfile import TemporaryDirectory, NamedTemporaryFile
from typing import Dict, List, Union, Set, Optional

USE_RBE = 100  # Percentage of tests that can use RBE (between 0 and 100)

lock_file = None  # Keep alive as long as this process is alive.

RBE_D8_DISABLED_FOR = {
  "952-invoke-custom",        # b/228312861: RBE uses wrong inputs.
  "979-const-method-handle",  # b/228312861: RBE uses wrong inputs.
}

# Debug option. Report commands that are taking a lot of user CPU time.
REPORT_SLOW_COMMANDS = False

class BuildTestContext:
  def __init__(self, args, android_build_top, test_dir):
    self.android_build_top = android_build_top.absolute()
    self.bootclasspath = args.bootclasspath.absolute()
    self.test_name = test_dir.name
    self.test_dir = test_dir.absolute()
    self.mode = args.mode
    self.jvm = (self.mode == "jvm")
    self.host = (self.mode == "host")
    self.target = (self.mode == "target")
    assert self.jvm or self.host or self.target

    self.java_home = Path(os.environ.get("JAVA_HOME")).absolute()
    self.java_path = self.java_home / "bin/java"
    self.javac_path = self.java_home / "bin/javac"
    self.javac_args = "-g -Xlint:-options"

    # Helper functions to execute tools.
    self.d8 = functools.partial(self.run, args.d8.absolute())
    self.jasmin = functools.partial(self.run, args.jasmin.absolute())
    self.javac = functools.partial(self.run, self.javac_path)
    self.smali = functools.partial(self.run, args.smali.absolute())
    self.soong_zip = functools.partial(self.run, args.soong_zip.absolute())
    self.zipalign = functools.partial(self.run, args.zipalign.absolute())
    if args.hiddenapi:
      self.hiddenapi = functools.partial(self.run, args.hiddenapi.absolute())

    # RBE wrapper for some of the tools.
    if "RBE_server_address" in os.environ and USE_RBE > (hash(self.test_name) % 100):
      self.rbe_exec_root = os.environ.get("RBE_exec_root")
      self.rbe_rewrapper = self.android_build_top / "prebuilts/remoteexecution-client/live/rewrapper"

      # TODO(b/307932183) Regression: RBE produces wrong output for D8 in ART
      disable_d8 = any((self.test_dir / n).exists() for n in ["classes", "src2", "src-art"])

      if self.test_name not in RBE_D8_DISABLED_FOR and not disable_d8:
        self.d8 = functools.partial(self.rbe_d8, args.d8.absolute())
      self.javac = functools.partial(self.rbe_javac, self.javac_path)
      self.smali = functools.partial(self.rbe_smali, args.smali.absolute())

    # Minimal environment needed for bash commands that we execute.
    self.bash_env = {
      "ANDROID_BUILD_TOP": self.android_build_top,
      "D8": args.d8.absolute(),
      "JAVA": self.java_path,
      "JAVAC": self.javac_path,
      "JAVAC_ARGS": self.javac_args,
      "JAVA_HOME": self.java_home,
      "PATH": os.environ["PATH"],
      "PYTHONDONTWRITEBYTECODE": "1",
      "SMALI": args.smali.absolute(),
      "SOONG_ZIP": args.soong_zip.absolute(),
      "TEST_NAME": self.test_name,
    }

  def bash(self, cmd):
    return subprocess.run(cmd,
                          shell=True,
                          cwd=self.test_dir,
                          env=self.bash_env,
                          check=True)

  def run(self, executable: pathlib.Path, args: List[Union[pathlib.Path, str]]):
    assert isinstance(executable, pathlib.Path), executable
    cmd: List[Union[pathlib.Path, str]] = []
    if REPORT_SLOW_COMMANDS:
      cmd += ["/usr/bin/time"]
    if executable.suffix == ".sh":
      cmd += ["/bin/bash"]
    cmd += [executable]
    cmd += args
    env = self.bash_env
    env.update({k: v for k, v in os.environ.items() if k.startswith("RBE_")})
    # Make paths relative as otherwise we could create too long command line.
    for i, arg in enumerate(cmd):
      if isinstance(arg, pathlib.Path):
        assert arg.absolute(), arg
        cmd[i] = relpath(arg, self.test_dir)
      elif isinstance(arg, list):
        assert all(p.absolute() for p in arg), arg
        cmd[i] = ":".join(relpath(p, self.test_dir) for p in arg)
      else:
        assert isinstance(arg, str), arg
    p = subprocess.run(cmd,
                       encoding=sys.stdout.encoding,
                       cwd=self.test_dir,
                       env=self.bash_env,
                       stderr=subprocess.STDOUT,
                       stdout=subprocess.PIPE)
    if REPORT_SLOW_COMMANDS:
      m = re.search("([0-9\.]+)user", p.stdout)
      assert m, p.stdout
      t = float(m.group(1))
      if t > 1.0:
        cmd_text = " ".join(map(str, cmd[1:]))[:100]
        print(f"[{self.test_name}] Command took {t:.2f}s: {cmd_text}")

    if p.returncode != 0:
      raise Exception("Command failed with exit code {}\n$ {}\n{}".format(
                      p.returncode, " ".join(map(str, cmd)), p.stdout))
    return p

  def rbe_wrap(self, args, inputs: Set[pathlib.Path]=None):
    with NamedTemporaryFile(mode="w+t") as input_list:
      inputs = inputs or set()
      for i, arg in enumerate(args):
        if isinstance(arg, pathlib.Path):
          assert arg.absolute(), arg
          inputs.add(arg)
        elif isinstance(arg, list):
          assert all(p.absolute() for p in arg), arg
          inputs.update(arg)
      input_list.writelines([relpath(i, self.rbe_exec_root)+"\n" for i in inputs])
      input_list.flush()
      return self.run(self.rbe_rewrapper, [
        "--platform=" + os.environ["RBE_platform"],
        "--input_list_paths=" + input_list.name,
      ] + args)

  def rbe_javac(self, javac_path:Path, args):
    output = relpath(Path(args[args.index("-d") + 1]), self.rbe_exec_root)
    return self.rbe_wrap(["--output_directories", output, javac_path] + args)

  def rbe_d8(self, d8_path:Path, args):
    inputs = set([d8_path.parent.parent / "framework/d8.jar"])
    output = relpath(Path(args[args.index("--output") + 1]), self.rbe_exec_root)
    return self.rbe_wrap([
      "--output_files" if output.endswith(".jar") else "--output_directories", output,
      "--toolchain_inputs=prebuilts/jdk/jdk17/linux-x86/bin/java",
      d8_path] + args, inputs)

  def rbe_smali(self, smali_path:Path, args):
    inputs = set([smali_path.parent.parent / "framework/smali.jar"])
    output = relpath(Path(args[args.index("--output") + 1]), self.rbe_exec_root)
    return self.rbe_wrap([
      "--output_files", output,
      "--toolchain_inputs=prebuilts/jdk/jdk17/linux-x86/bin/java",
      smali_path] + args, inputs)

  def build(self) -> None:
    script = self.test_dir / "build.py"
    if script.exists():
      module = SourceFileLoader("build_" + self.test_name,
                                str(script)).load_module()
      module.build(self)
    else:
      self.default_build()

  def default_build(
      self,
      use_desugar=True,
      use_hiddenapi=True,
      need_dex=None,
      zip_compression_method="deflate",
      zip_align_bytes=None,
      api_level:Union[int, str]=26,  # Can also be named alias (string).
      javac_args=[],
      javac_classpath: List[Path]=[],
      d8_flags=[],
      smali_args=[],
      use_smali=True,
      use_jasmin=True,
      javac_source_arg="1.8",
      javac_target_arg="1.8"
    ):
    javac_classpath = javac_classpath.copy()  # Do not modify default value.

    # Wrap "pathlib.Path" with our own version that ensures all paths are absolute.
    # Plain filenames are assumed to be relative to self.test_dir and made absolute.
    class Path(pathlib.Path):
      def __new__(cls, filename: str):
        path = pathlib.Path(filename)
        return path if path.is_absolute() else (self.test_dir / path)

    need_dex = (self.host or self.target) if need_dex is None else need_dex

    if self.jvm:
      # No desugaring on jvm because it supports the latest functionality.
      use_desugar = False

    # Set API level for smali and d8.
    if isinstance(api_level, str):
      API_LEVEL = {
        "default-methods": 24,
        "parameter-annotations": 25,
        "agents": 26,
        "method-handles": 26,
        "var-handles": 28,
      }
      api_level = API_LEVEL[api_level]
    assert isinstance(api_level, int), api_level

    def zip(zip_target: Path, *files: Path):
      zip_args = ["-o", zip_target, "-C", zip_target.parent]
      if zip_compression_method == "store":
        zip_args.extend(["-L", "0"])
      for f in files:
        zip_args.extend(["-f", f])
      self.soong_zip(zip_args)

      if zip_align_bytes:
        # zipalign does not operate in-place, so write results to a temp file.
        with TemporaryDirectory() as tmp_dir:
          tmp_file = Path(tmp_dir) / "aligned.zip"
          self.zipalign(["-f", str(zip_align_bytes), zip_target, tmp_file])
          # replace original zip target with our temp file.
          tmp_file.rename(zip_target)


    def make_jasmin(dst_dir: Path, src_dir: Path) -> Optional[Path]:
      if not use_jasmin or not src_dir.exists():
        return None  # No sources to compile.
      dst_dir.mkdir()
      self.jasmin(["-d", dst_dir] + sorted(src_dir.glob("**/*.j")))
      return dst_dir

    def make_smali(dst_dex: Path, src_dir: Path) -> Optional[Path]:
      if not use_smali or not src_dir.exists():
        return None  # No sources to compile.
      p = self.smali(["-JXmx512m", "assemble"] + smali_args + ["--api", str(api_level)] +
                     ["--output", dst_dex] + sorted(src_dir.glob("**/*.smali")))
      assert dst_dex.exists(), p.stdout  # NB: smali returns 0 exit code even on failure.
      return dst_dex

    def make_java(dst_dir: Path, *src_dirs: Path) -> Optional[Path]:
      if not any(src_dir.exists() for src_dir in src_dirs):
        return None  # No sources to compile.
      dst_dir.mkdir(exist_ok=True)
      args = self.javac_args.split(" ") + javac_args
      args += ["-implicit:none", "-encoding", "utf8", "-d", dst_dir]
      args += ["-source", javac_source_arg, "-target", javac_target_arg]
      if not self.jvm and float(javac_target_arg) < 17.0:
        args += ["-bootclasspath", self.bootclasspath]
      if javac_classpath:
        args += ["-classpath", javac_classpath]
      for src_dir in src_dirs:
        args += sorted(src_dir.glob("**/*.java"))
      self.javac(args)
      javac_post = Path("javac_post.sh")
      if javac_post.exists():
        self.run(javac_post, [dst_dir])
      return dst_dir


    # Make a "dex" file given a directory of classes. This will be
    # packaged in a jar file.
    def make_dex(src_dir: Path):
      dst_jar = Path(src_dir.name + ".jar")
      args = d8_flags + ["--min-api", str(api_level), "--output", dst_jar]
      args += ["--lib", self.bootclasspath] if use_desugar else ["--no-desugaring"]
      args += sorted(src_dir.glob("**/*.class"))
      self.d8(args)

      # D8 outputs to JAR files today rather than DEX files as DX used
      # to. To compensate, we extract the DEX from d8's output to meet the
      # expectations of make_dex callers.
      dst_dex = Path(src_dir.name + ".dex")
      with TemporaryDirectory() as tmp_dir:
        zipfile.ZipFile(dst_jar, "r").extractall(tmp_dir)
        (Path(tmp_dir) / "classes.dex").rename(dst_dex)

    # Merge all the dex files.
    # Skip non-existing files, but at least 1 file must exist.
    def make_dexmerge(dst_dex: Path, *src_dexs: Path):
      # Include destination. Skip any non-existing files.
      srcs = [f for f in [dst_dex] + list(src_dexs) if f.exists()]

      # NB: We merge even if there is just single input.
      # It is useful to normalize non-deterministic smali output.
      tmp_dir = self.test_dir / "dexmerge"
      tmp_dir.mkdir()
      self.d8(["--min-api", str(api_level), "--output", tmp_dir] + srcs)
      assert not (tmp_dir / "classes2.dex").exists()
      for src_file in srcs:
        src_file.unlink()
      (tmp_dir / "classes.dex").rename(dst_dex)
      tmp_dir.rmdir()


    def make_hiddenapi(*dex_files: Path):
      if not use_hiddenapi or not Path("hiddenapi-flags.csv").exists():
        return  # Nothing to do.
      args: List[Union[str, Path]] = ["encode"]
      for dex_file in dex_files:
        args.extend(["--input-dex=" + str(dex_file), "--output-dex=" + str(dex_file)])
      args.append("--api-flags=hiddenapi-flags.csv")
      args.append("--no-force-assign-all")
      self.hiddenapi(args)


    if Path("classes.dex").exists():
      zip(Path(self.test_name + ".jar"), Path("classes.dex"))
      return

    if Path("classes.dm").exists():
      zip(Path(self.test_name + ".jar"), Path("classes.dm"))
      return

    if make_jasmin(Path("jasmin_classes"), Path("jasmin")):
      javac_classpath.append(Path("jasmin_classes"))

    if make_jasmin(Path("jasmin_classes2"), Path("jasmin-multidex")):
      javac_classpath.append(Path("jasmin_classes2"))

    # To allow circular references, compile src/, src-multidex/, src-aotex/,
    # src-bcpex/, src-ex/ together and pass the output as class path argument.
    # Replacement sources in src-art/, src2/ and src-ex2/ can replace symbols
    # used by the other src-* sources we compile here but everything needed to
    # compile the other src-* sources should be present in src/ (and jasmin*/).
    extra_srcs = ["src-multidex", "src-aotex", "src-bcpex", "src-ex"]
    replacement_srcs = ["src2", "src-ex2"] + ([] if self.jvm else ["src-art"])
    if (Path("src").exists() and
        any(Path(p).exists() for p in extra_srcs + replacement_srcs)):
      make_java(Path("classes-tmp-all"), Path("src"), *map(Path, extra_srcs))
      javac_classpath.append(Path("classes-tmp-all"))

    if make_java(Path("classes-aotex"), Path("src-aotex")) and need_dex:
      make_dex(Path("classes-aotex"))
      # rename it so it shows up as "classes.dex" in the zip file.
      Path("classes-aotex.dex").rename(Path("classes.dex"))
      zip(Path(self.test_name + "-aotex.jar"), Path("classes.dex"))

    if make_java(Path("classes-bcpex"), Path("src-bcpex")) and need_dex:
      make_dex(Path("classes-bcpex"))
      # rename it so it shows up as "classes.dex" in the zip file.
      Path("classes-bcpex.dex").rename(Path("classes.dex"))
      zip(Path(self.test_name + "-bcpex.jar"), Path("classes.dex"))

    make_java(Path("classes"), Path("src"))

    if not self.jvm:
      # Do not attempt to build src-art directories on jvm,
      # since it would fail without libcore.
      make_java(Path("classes"), Path("src-art"))

    if make_java(Path("classes2"), Path("src-multidex")) and need_dex:
      make_dex(Path("classes2"))

    make_java(Path("classes"), Path("src2"))

    # If the classes directory is not-empty, package classes in a DEX file.
    # NB: some tests provide classes rather than java files.
    if any(Path("classes").glob("*")) and need_dex:
      make_dex(Path("classes"))

    if Path("jasmin_classes").exists():
      # Compile Jasmin classes as if they were part of the classes.dex file.
      if need_dex:
        make_dex(Path("jasmin_classes"))
        make_dexmerge(Path("classes.dex"), Path("jasmin_classes.dex"))
      else:
        # Move jasmin classes into classes directory so that they are picked up
        # with -cp classes.
        Path("classes").mkdir(exist_ok=True)
        copytree(Path("jasmin_classes"), Path("classes"), dirs_exist_ok=True)

    if need_dex and make_smali(Path("smali_classes.dex"), Path("smali")):
      # Merge smali files into classes.dex,
      # this takes priority over any jasmin files.
      make_dexmerge(Path("classes.dex"), Path("smali_classes.dex"))

    # Compile Jasmin classes in jasmin-multidex as if they were part of
    # the classes2.jar
    if Path("jasmin-multidex").exists():
      if need_dex:
        make_dex(Path("jasmin_classes2"))
        make_dexmerge(Path("classes2.dex"), Path("jasmin_classes2.dex"))
      else:
        # Move jasmin classes into classes2 directory so that
        # they are picked up with -cp classes2.
        Path("classes2").mkdir()
        copytree(Path("jasmin_classes2"), Path("classes2"), dirs_exist_ok=True)
        rmtree(Path("jasmin_classes2"))

    if need_dex and make_smali(Path("smali_classes2.dex"), Path("smali-multidex")):
      # Merge smali_classes2.dex into classes2.dex
      make_dexmerge(Path("classes2.dex"), Path("smali_classes2.dex"))

    make_java(Path("classes-ex"), Path("src-ex"))

    make_java(Path("classes-ex"), Path("src-ex2"))

    if Path("classes-ex").exists() and need_dex:
      make_dex(Path("classes-ex"))

    if need_dex and make_smali(Path("smali_classes-ex.dex"), Path("smali-ex")):
      # Merge smali files into classes-ex.dex.
      make_dexmerge(Path("classes-ex.dex"), Path("smali_classes-ex.dex"))

    if Path("classes-ex.dex").exists():
      # Apply hiddenapi on the dex files if the test has API list file(s).
      make_hiddenapi(Path("classes-ex.dex"))

      # quick shuffle so that the stored name is "classes.dex"
      Path("classes.dex").rename(Path("classes-1.dex"))
      Path("classes-ex.dex").rename(Path("classes.dex"))
      zip(Path(self.test_name + "-ex.jar"), Path("classes.dex"))
      Path("classes.dex").rename(Path("classes-ex.dex"))
      Path("classes-1.dex").rename(Path("classes.dex"))

    # Apply hiddenapi on the dex files if the test has API list file(s).
    if need_dex:
      if any(Path(".").glob("*-multidex")):
        make_hiddenapi(Path("classes.dex"), Path("classes2.dex"))
      else:
        make_hiddenapi(Path("classes.dex"))

    # Create a single dex jar with two dex files for multidex.
    if need_dex:
      if Path("classes2.dex").exists():
        zip(Path(self.test_name + ".jar"), Path("classes.dex"), Path("classes2.dex"))
      else:
        zip(Path(self.test_name + ".jar"), Path("classes.dex"))


# If we build just individual shard, we want to split the work among all the cores,
# but if the build system builds all shards, we don't want to overload the machine.
# We don't know which situation we are in, so as simple work-around, we use a lock
# file to allow only one shard to use multiprocessing at the same time.
def use_multiprocessing(mode: str) -> bool:
  if "RBE_server_address" in os.environ:
    return True
  global lock_file
  lock_path = Path(environ["TMPDIR"]) / ("art-test-run-test-build-py-" + mode)
  lock_file = open(lock_path, "w")
  try:
    lockf(lock_file, LOCK_EX | LOCK_NB)
    return True  # We are the only instance of this script in the build system.
  except BlockingIOError:
    return False  # Some other instance is already running.


def main() -> None:
  parser = ArgumentParser(description=__doc__)
  parser.add_argument("--out", type=Path, help="Final zip file")
  parser.add_argument("--mode", choices=["host", "jvm", "target"])
  parser.add_argument("--bootclasspath", type=Path)
  parser.add_argument("--d8", type=Path)
  parser.add_argument("--hiddenapi", type=Path)
  parser.add_argument("--jasmin", type=Path)
  parser.add_argument("--smali", type=Path)
  parser.add_argument("--soong_zip", type=Path)
  parser.add_argument("--zipalign", type=Path)
  parser.add_argument("srcs", nargs="+", type=Path)
  args = parser.parse_args()

  android_build_top = Path(getcwd()).absolute()
  ziproot = args.out.absolute().parent / "zip"
  srcdirs = set(s.parents[-4].absolute() for s in args.srcs)

  # Special hidden-api shard: If the --hiddenapi flag is provided, build only
  # hiddenapi tests. Otherwise exclude all hiddenapi tests from normal shards.
  def filter_by_hiddenapi(srcdir: Path) -> bool:
    return (args.hiddenapi != None) == ("hiddenapi" in srcdir.name)

  # Initialize the test objects.
  # We need to do this before we change the working directory below.
  tests: List[BuildTestContext] = []
  for srcdir in filter(filter_by_hiddenapi, srcdirs):
    dstdir = ziproot / args.mode / srcdir.name
    copytree(srcdir, dstdir)
    tests.append(BuildTestContext(args, android_build_top, dstdir))

  # We can not change the working directory per each thread since they all run in parallel.
  # Create invalid read-only directory to catch accidental use of current working directory.
  with TemporaryDirectory("-do-not-use-cwd") as invalid_tmpdir:
    os.chdir(invalid_tmpdir)
    os.chmod(invalid_tmpdir, 0)
    with ThreadPoolExecutor(cpu_count() if use_multiprocessing(args.mode) else 1) as pool:
      jobs = {}
      for ctx in tests:
        jobs[ctx.test_name] = pool.submit(ctx.build)
      for test_name, job in jobs.items():
        try:
          job.result()
        except Exception as e:
          raise Exception("Failed to build " + test_name) from e

  # Create the final zip file which contains the content of the temporary directory.
  proc = run([android_build_top / args.soong_zip, "-o", android_build_top / args.out,
              "-C", ziproot, "-D", ziproot], check=True)


if __name__ == "__main__":
  main()
