# Copyright 2020 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.

"""Bazel Bundletool Commands."""

load(":common.bzl", _common = "common")
load(":java.bzl", _java = "java")

_density_mapping = {
    "ldpi": 120,
    "mdpi": 160,
    "hdpi": 240,
    "xhdpi": 320,
    "xxhdpi": 480,
    "xxxhdpi": 640,
    "tvdpi": 213,
}

def _proto_apk_to_module(
        ctx,
        out = None,
        proto_apk = None,
        zip = None,
        unzip = None):
    # TODO(timpeut): rewrite this as a standalone golang tool
    ctx.actions.run_shell(
        command = """
set -e

IN_DIR=$(mktemp -d)
OUT_DIR=$(mktemp -d)
CUR_PWD=$(pwd)
UNZIP=%s
ZIP=%s
INPUT=%s
OUTPUT=%s

"${UNZIP}" -qq "${INPUT}" -d "${IN_DIR}"
cd "${IN_DIR}"

if [ -f resources.pb ]; then
  mv resources.pb "${OUT_DIR}/"
fi

if [ -f AndroidManifest.xml ]; then
  mkdir "${OUT_DIR}/manifest"
  mv AndroidManifest.xml "${OUT_DIR}/manifest/"
fi

NUM_DEX=`ls -1 *.dex 2>/dev/null | wc -l`
if [ $NUM_DEX != 0 ]; then
  mkdir "${OUT_DIR}/dex"
  mv *.dex "${OUT_DIR}/dex/"
fi

if [ -d res ]; then
  mv res "${OUT_DIR}/res"
fi

if [ -d assets ]; then
  mv assets "${OUT_DIR}/"
fi

if [ -d lib ]; then
  mv lib "${OUT_DIR}/"
fi

UNKNOWN=`ls -1 * 2>/dev/null | wc -l`
if [ $UNKNOWN != 0 ]; then
  mkdir "${OUT_DIR}/root"
  mv * "${OUT_DIR}/root/"
fi

cd "${OUT_DIR}"
"${CUR_PWD}/${ZIP}" "${CUR_PWD}/${OUTPUT}" -Drq0 .
""" % (
            unzip.executable.path,
            zip.executable.path,
            proto_apk.path,
            out.path,
        ),
        tools = [zip, unzip],
        arguments = [],
        inputs = [proto_apk],
        outputs = [out],
        mnemonic = "Rebundle",
        progress_message = "Rebundle to %s" % out.short_path,
    )

def _build(
        ctx,
        out = None,
        modules = [],
        config = None,
        metadata = dict(),
        bundletool = None,
        host_javabase = None):
    args = ctx.actions.args()
    args.add("build-bundle")
    args.add("--output", out)
    if modules:
        args.add_joined("--modules", modules, join_with = ",")
    if config:
        args.add("--config", config)
    for path, f in metadata.items():
        args.add("--metadata-file", "%s:%s" % (path, f.path))

    _java.run(
        ctx = ctx,
        host_javabase = host_javabase,
        executable = bundletool,
        arguments = [args],
        inputs = (
            modules +
            ([config] if config else []) +
            metadata.values()
        ),
        outputs = [out],
        mnemonic = "BuildBundle",
        progress_message = "Building bundle %s" % out.short_path,
    )

def _extract_config(
        ctx,
        out = None,
        aab = None,
        bundletool = None,
        host_javabase = None):
    # Need to execute as a shell script as the tool outputs to stdout
    cmd = """
set -e
contents=`%s -jar %s dump config --bundle %s`
echo "$contents" > %s
""" % (
        host_javabase[java_common.JavaRuntimeInfo].java_executable_exec_path,
        bundletool.executable.path,
        aab.path,
        out.path,
    )

    ctx.actions.run_shell(
        inputs = [aab],
        outputs = [out],
        tools = depset([bundletool.executable], transitive = [host_javabase[java_common.JavaRuntimeInfo].files]),
        mnemonic = "ExtractBundleConfig",
        progress_message = "Extract bundle config to %s" % out.short_path,
        command = cmd,
    )

def _extract_manifest(
        ctx,
        out = None,
        aab = None,
        module = None,
        xpath = None,
        bundletool = None,
        host_javabase = None):
    # Need to execute as a shell script as the tool outputs to stdout
    extra_flags = []
    if module:
        extra_flags.append("--module " + module)
    if xpath:
        extra_flags.append("--xpath " + xpath)
    cmd = """
set -e
contents=`%s -jar %s dump manifest --bundle %s %s`
echo "$contents" > %s
""" % (
        host_javabase[java_common.JavaRuntimeInfo].java_executable_exec_path,
        bundletool.executable.path,
        aab.path,
        " ".join(extra_flags),
        out.path,
    )

    ctx.actions.run_shell(
        inputs = [aab],
        outputs = [out],
        tools = depset([bundletool.executable], transitive = [host_javabase[java_common.JavaRuntimeInfo].files]),
        mnemonic = "ExtractBundleManifest",
        progress_message = "Extract bundle manifest to %s" % out.short_path,
        command = cmd,
    )

def _bundle_to_apks(
        ctx,
        out = None,
        bundle = None,
        mode = None,
        system_apk_options = None,
        device_spec = None,
        keystore = None,
        oldest_signer = None,
        lineage = None,
        rotation_min_sdk = None,
        modules = None,
        aapt2 = None,
        bundletool = None,
        host_javabase = None):
    inputs = [bundle]
    args = ctx.actions.args()
    args.add("build-apks")
    args.add("--output", out)
    args.add("--bundle", bundle)
    args.add("--aapt2", aapt2.executable.path)

    if mode:
        args.add("--mode", mode)

    if system_apk_options:
        if mode != "SYSTEM":
            fail("Unexpected system_apk_options specified, requires SYSTEM mode but got %s" % mode)
        args.add_joined("--system-apk-options", system_apk_options, join_with = ",")

    if keystore:
        args.add("--ks", keystore.path)
        args.add("--ks-pass", "pass:android")
        args.add("--ks-key-alias", "AndroidDebugKey")
        inputs.append(keystore)

    if lineage:
        if not oldest_signer:
            fail("Key rotation requires oldest_signer in %s" % ctx.label)
        oldest_signer_properties = _common.create_signer_properties(ctx, oldest_signer)
        args.add("--oldest-signer", oldest_signer_properties.path)
        args.add("--lineage", lineage.short_path)
        inputs.append(oldest_signer_properties)
        inputs.append(oldest_signer)
        inputs.append(lineage)

    if rotation_min_sdk:
        args.add("--rotation-min-sdk-version", rotation_min_sdk)

    if device_spec:
        args.add("--device-spec", device_spec)
        inputs.append(device_spec)

    if modules:
        args.add_joined("--modules", modules, join_with = ",")

    _java.run(
        ctx = ctx,
        host_javabase = host_javabase,
        executable = bundletool,
        arguments = [args],
        inputs = inputs,
        outputs = [out],
        tools = [aapt2],
        mnemonic = "BundleToApks",
        progress_message = "Converting bundle to .apks: %s" % out.short_path,
    )

def _build_device_json(
        ctx,
        out,
        abis,
        locales,
        density,
        sdk_version):
    json_content = json.encode(struct(
        supportedAbis = abis,
        supportedLocales = locales,
        screenDensity = _density_mapping[density],
        sdkVersion = int(sdk_version),
    ))
    ctx.actions.write(out, json_content)

bundletool = struct(
    build = _build,
    build_device_json = _build_device_json,
    bundle_to_apks = _bundle_to_apks,
    extract_config = _extract_config,
    extract_manifest = _extract_manifest,
    proto_apk_to_module = _proto_apk_to_module,
)
