#!/usr/bin/env python
#
# Copyright (C) 2016 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.
#
import argparse
import logging
import os
from pathlib import Path
import shutil
import subprocess
from tempfile import TemporaryDirectory
import textwrap


THIS_DIR = Path(__file__).resolve().parent


def logger():
    return logging.getLogger(__name__)


def check_call(cmd):
    logger().debug("Running `%s`", " ".join(cmd))
    subprocess.check_call(cmd)


def remove(path):
    logger().debug("remove `%s`", path)
    os.remove(path)


def fetch_artifact(branch: str, build: str, pattern: str) -> None:
    """Fetches an artifact from the build server.

    Use OAuth2 authentication and the gLinux android-fetch-artifact package,
    which work with both on-corp and off-corp workstations."""
    fetch_artifact_path = shutil.which("fetch_artifact")
    if fetch_artifact_path is None:
        raise RuntimeError(
            "error: cannot find fetch_artifact in PATH. Install it using:\n"
            "  sudo glinux-add-repo android\n"
            "  sudo apt update\n"
            "  sudo apt install android-fetch-artifact\n"
        )
    cmd = [
        fetch_artifact_path,
        "--use_oauth2",
        "--branch",
        branch,
        "--target=linux",
        "--bid",
        build,
        pattern,
    ]
    check_call(cmd)


def api_str(api_level):
    return f"android-{api_level}"


def start_branch(build):
    branch_name = "update-" + (build or "latest")
    logger().info("Creating branch %s", branch_name)
    check_call(["repo", "start", branch_name, "."])


def remove_old_release(install_dir: Path) -> None:
    if (install_dir / ".git").exists():
        logger().info('Removing old install directory "%s"', install_dir)
        check_call(["git", "rm", "-rf", install_dir])

    # Need to check again because git won't remove directories if they have
    # non-git files in them.
    if install_dir.exists():
        shutil.rmtree(install_dir)


LIBUNWIND_GLOB = "toolchains/llvm/prebuilt/*/lib64/clang/*/lib/linux/*/libunwind.a"
LIBCXX_SHARED_GLOB = (
    "toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/*/libc++_shared.so"
)
LIBCXX_STATIC_GLOB = (
    "toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/*/libc++_static.a"
)
LIBCXXABI_GLOB = "toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/*/libc++abi.a"


def unzip_single_directory(artifact: Path, destination: Path) -> None:
    # Use cwd so that we can use rename without having to worry about crossing
    # file systems.
    with TemporaryDirectory(dir=os.getcwd()) as temp_dir:
        cmd = [
            "unzip",
            str(artifact),
            "-d",
            temp_dir,
            "*/sources/android/cpufeatures/*",
            "*/sources/android/native_app_glue/*",
            "*/sources/android/support/*",
            "*/sources/cxx-stl/*",
            "*/source.properties",
            os.path.join("*", LIBUNWIND_GLOB),
            os.path.join("*", LIBCXX_SHARED_GLOB),
            os.path.join("*", LIBCXX_STATIC_GLOB),
            os.path.join("*", LIBCXXABI_GLOB),
        ]
        check_call(cmd)

        dirs = os.listdir(temp_dir)
        assert len(dirs) == 1
        ndk_dir = Path(temp_dir) / dirs[0]
        for child in ndk_dir.iterdir():
            child.rename(destination / child.name)


def relocate_libcxx(install_dir: Path) -> None:
    """Copies the libc++ libraries from the toolchain to sources.

    New versions of the NDK have removed the libraries in the sources directory because
    they are duplicates and they aren't needed in typical builds. Soong still expects to
    find them in that directory though. We could fix Soong, but since this whole
    directory should be dead soon we'll just fix-up the install for now.
    """
    dest_base = install_dir / "sources/cxx-stl/llvm-libc++/libs"
    for glob in {LIBCXX_SHARED_GLOB, LIBCXX_STATIC_GLOB, LIBCXXABI_GLOB}:
        file_name = Path(glob).name
        for file_path in install_dir.glob(glob):
            triple = file_path.parent.name
            abi = {
                "arm-linux-androideabi": "armeabi-v7a",
                "aarch64-linux-android": "arm64-v8a",
                "i686-linux-android": "x86",
                "x86_64-linux-android": "x86_64",
            }[triple]
            dest_dir = dest_base / abi
            dest_dir.mkdir(parents=True, exist_ok=True)
            dest = dest_dir / file_name
            logger().info("Relocating %s to %s", file_path, dest)
            file_path.rename(dest)


def relocate_libunwind(install_dir: Path) -> None:
    dest_base = install_dir / "sources/cxx-stl/llvm-libc++/libs"
    for libunwind in install_dir.glob(LIBUNWIND_GLOB):
        arch = libunwind.parent.name
        abi = {
            "arm": "armeabi-v7a",
            "aarch64": "arm64-v8a",
            "i386": "x86",
            "x86_64": "x86_64",
        }[arch]
        dest_dir = dest_base / abi
        dest = dest_dir / "libunwind.a"
        logger().info("Relocating %s to %s", libunwind, dest)
        libunwind.rename(dest)


def delete_android_mks(install_dir: Path) -> None:
    for android_mk in install_dir.glob("**/Android.mk"):
        android_mk.unlink()


def install_new_release(branch: str, build: str, install_dir: Path) -> None:
    install_dir.mkdir()

    artifact_pattern = "android-ndk-*.zip"
    logger().info(
        "Fetching %s from %s (artifacts matching %s)", build, branch, artifact_pattern
    )
    fetch_artifact(branch, build, artifact_pattern)
    artifacts = list(Path().glob("android-ndk-*.zip"))
    try:
        assert len(artifacts) == 1
        artifact = artifacts[0]

        logger().info("Extracting release")
        unzip_single_directory(artifact, install_dir)
        relocate_libcxx(install_dir)
        relocate_libunwind(install_dir)
        delete_android_mks(install_dir)
    finally:
        for artifact in artifacts:
            artifact.unlink()


def commit(branch: str, build: str, install_dir: Path) -> None:
    logger().info("Making commit")
    check_call(["git", "add", str(install_dir)])
    message = textwrap.dedent(
        f"""\
        Update NDK prebuilts to build {build}.

        Taken from branch {branch}.

        Bug: None
        Test: treehugger
        """
    )
    check_call(["git", "commit", "-m", message])


def get_args():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "-b", "--branch", default="master-ndk", help="Branch to pull build from."
    )
    parser.add_argument("--build", required=True, help="Build number to pull.")
    parser.add_argument(
        "--use-current-branch",
        action="store_true",
        help="Perform the update in the current branch. Do not repo start.",
    )
    parser.add_argument(
        "-v", "--verbose", action="count", default=0, help="Increase output verbosity."
    )
    return parser.parse_args()


def main() -> None:
    os.chdir(THIS_DIR)

    args = get_args()
    verbose_map = (logging.WARNING, logging.INFO, logging.DEBUG)
    verbosity = min(args.verbose, 2)
    logging.basicConfig(level=verbose_map[verbosity])

    install_dir = THIS_DIR / "current"

    if not args.use_current_branch:
        start_branch(args.build)
    remove_old_release(install_dir)
    install_new_release(args.branch, args.build, install_dir)
    commit(args.branch, args.build, install_dir)


if __name__ == "__main__":
    main()
