#!/bin/bash
# Copyright 2024 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.

# Dex and optionally minify supported Java 8 libs using d8/r8.

# --- begin runfiles.bash initialization v3 ---
# Copy-pasted from the Bazel Bash runfiles library v3.
set -uo pipefail; set +e; f=bazel_tools/tools/bash/runfiles/runfiles.bash
source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \
  source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \
  source "$0.runfiles/$f" 2>/dev/null || \
  source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
  source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
  { echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e
# --- end runfiles.bash initialization v3 ---

set -eu

# Keep rules generated by tracereferences.
rules=
# android.jar library.
android_jar=
# Application as class file (not dex).
binary_jar=
# Desugared library dex output.
dest=
# Desugared library mapping file output.
map=
# The minimal API level to be supported.
min_api=

function parse_args() {
  while [[ "$#" -gt 0 ]]; do
    arg="$1"; shift;
    case "${arg}" in
      --rules) rules="$1"; shift ;;
      --rules=*) rules="${arg:8}" ;;
      --binary) binary_jar="$1"; shift ;;
      --binary=*) binary_jar="${arg:9}" ;;
      --output) dest="$1"; shift ;;
      --output=*) dest="${arg:9}" ;;
      --output_map) map="$1"; shift ;;
      --output_map=*) map="${arg:13}" ;;
      --android_jar) android_jar="$1"; shift ;;
      --android_jar=*) android_jar="${arg:14}" ;;
      --min-api) min_api="$1"; shift ;;
      --min-api=*) min_api="${arg:10}" ;;
      *) echo "Unknown flag: ${arg}"; exit 1 ;;
    esac
  done
}

declare -a ARGS_FROM_PARAMS_FILE
PARAMS_TXT=$(rlocation rules_android/tools/android/build_java8_legacy_dex_params.txt)
read -ra ARGS_FROM_PARAMS_FILE <<< "$(cat $PARAMS_TXT)"

parse_args "${ARGS_FROM_PARAMS_FILE[@]}" "$@"

todex="$(rlocation rules_android/tools/android/desugared_jdk_libs.jar)"
# Only pass the --pg-map-output if a mapping file output location is provided
map_output=
if [[ -n "${map}" ]]; then
  map_output="--pg-map-output"
fi
if [[ -n "${binary_jar}" ]]; then
  tmpdir=$(mktemp -d)

  # Collect keep rules from references in binary.
  if [[ -z "${rules}" ]]; then
    rules="${tmpdir}/rules.pgcfg"
  fi
  "$(rlocation rules_android/tools/android/tracereferences)" \
      --map-diagnostics:MissingDefinitionsDiagnostic error warning \
      --keep-rules \
      --lib "${android_jar}" \
      --source "${binary_jar}" \
      --target "${todex}" \
      --output "${rules}"

  if [[ ! -s "${rules}" ]]; then
    # No keep rules, meaning nothing to keep, so emit an empty zip
    "$(rlocation rules_android/tools/android/zip)" -jt -X "${dest}" "${rules}"
    "$(rlocation rules_android/tools/android/zip)" -jt -X -d "${dest}" "${rules}"
    if [[ -n "${map}" ]]; then
      echo '# No desugared library mapping' > "${map}"
    fi
  else
    # Shrink desugared library and convert to DEX.
    "$(rlocation rules_android/tools/android/r8)" \
        --min-api "${min_api}" \
        --no-desugaring \
        --lib "${android_jar}" \
        --pg-conf "$(rlocation rules_android/tools/android/minify_desugar_jdk_libs.pgcfg)" \
        --pg-conf "${rules}" \
        --output "${dest}" \
        "${map_output}" "${map}" \
        "${todex}"
  fi

  rm -rf "${tmpdir}"
else
  # No shrinking just convert to DEX.
  "$(rlocation rules_android/tools/android/d8)" --min-api "${min_api}" --no-desugaring --lib "${android_jar}" --output "${dest}" "${todex}"
fi
