#!/usr/bin/env python3
# Copyright (c) 2023 Valve Corporation
# Copyright (c) 2023 LunarG, Inc.

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

# NOTE: Android this documentation is crucial for understanding the layout of the NDK.
# https://android.googlesource.com/platform/ndk/+/master/docs/BuildSystemMaintainers.md

# NOTE: Environment variables we can rely on users/environments setting.
# https://github.com/actions/runner-images/blob/main/images/linux/Ubuntu2204-Readme.md#environment-variables-2

import argparse
import os
import sys
import shutil
import subprocess

# helper to define paths relative to the repo root
def RepoRelative(path):
    return os.path.abspath(os.path.join(os.path.dirname(__file__), '..', path))

# Points to the directory containing the top level CMakeLists.txt
PROJECT_SRC_DIR = os.path.abspath(os.path.join(os.path.split(os.path.abspath(__file__))[0], '..'))
if not os.path.isfile(f'{PROJECT_SRC_DIR}/CMakeLists.txt'):
    print(f'PROJECT_SRC_DIR invalid! {PROJECT_SRC_DIR}')
    sys.exit(1)

# Runs a command in a directory and returns its return code.
# Directory is project root by default, or a relative path from project root
def RunShellCmd(command, start_dir = PROJECT_SRC_DIR, env=None, verbose=False):
    # Flush stdout here. Helps when debugging on CI.
    sys.stdout.flush()

    if start_dir != PROJECT_SRC_DIR:
        start_dir = RepoRelative(start_dir)
    cmd_list = command.split(" ")

    if verbose:
        print(f'CICMD({cmd_list}, env={env})')
    subprocess.check_call(cmd_list, cwd=start_dir, env=env)

# Manifest file describing out test application
def get_android_manifest() -> str:
    manifest = RepoRelative('cube/android/AndroidManifest.xml')
    if not os.path.isfile(manifest):
        print(f"Unable to find manifest for APK! {manifest}")
        sys.exit(-1)
    return manifest

# Generate the APK from the CMake binaries
def generate_apk(SDK_ROOT : str, CMAKE_INSTALL_DIR : str) -> str:
    apk_dir = RepoRelative('build-android/bin')

    # Delete APK directory since it could contain files from old runs
    if os.path.isdir(apk_dir):
        shutil.rmtree(apk_dir)

    shutil.copytree(CMAKE_INSTALL_DIR, apk_dir)

    android_manifest = get_android_manifest()

    android_jar = f"{SDK_ROOT}/platforms/android-26/android.jar"
    if not os.path.isfile(android_jar):
        print(f"Unable to find {android_jar}!")
        sys.exit(-1)

    apk_name = 'VkCube'

    unaligned_apk = f'{apk_dir}/{apk_name}-unaligned.apk'
    test_apk = f'{apk_dir}/{apk_name}.apk'

    # Create APK
    RunShellCmd(f'aapt package -f -M {android_manifest} -I {android_jar} -F {unaligned_apk} {CMAKE_INSTALL_DIR}')

    # Align APK
    RunShellCmd(f'zipalign -f 4 {unaligned_apk} {test_apk}')

    # Create Key (If it doesn't already exist)
    debug_key = RepoRelative(f'{apk_dir}/debug.keystore')
    ks_pass = 'android'
    if not os.path.isfile(debug_key):
        dname = 'CN=Android-Debug,O=Android,C=US'
        RunShellCmd(f'keytool -genkey -v -keystore {debug_key} -alias androiddebugkey -storepass {ks_pass} -keypass {ks_pass} -keyalg RSA -keysize 2048 -validity 10000 -dname {dname}')

    # Sign APK
    RunShellCmd(f'apksigner sign --verbose --ks {debug_key} --ks-pass pass:{ks_pass} {test_apk}')

# Android APKs can contain binaries for multiple ABIs (armeabi-v7a, arm64-v8a, x86, x86_64).
# https://en.wikipedia.org/wiki/Apk_(file_format)#Package_contents
#
# As a result CMake will need to be run multiple times to create a complete test APK that can be run on any Android device.
def main():
    configs = ['Release', 'Debug']

    parser = argparse.ArgumentParser()
    parser.add_argument('--config', type=str, choices=configs, default=configs[0])
    parser.add_argument('--app-abi', dest='android_abi', type=str, default="arm64-v8a")
    parser.add_argument('--app-stl', dest='android_stl', type=str, choices=["c++_static", "c++_shared"], default="c++_static")
    parser.add_argument('--apk', action='store_true', help='Generate an APK as a post build step.')
    parser.add_argument('--clean', action='store_true', help='Cleans CMake build artifacts')
    args = parser.parse_args()

    cmake_config = args.config
    android_abis = args.android_abi.split(" ")
    android_stl = args.android_stl
    create_apk = args.apk
    clean = args.clean

    if "ANDROID_NDK_HOME" not in os.environ:
        print("Cannot find ANDROID_NDK_HOME!")
        sys.exit(1)

    android_ndk_home = os.environ.get('ANDROID_NDK_HOME')
    android_toolchain = f'{android_ndk_home}/build/cmake/android.toolchain.cmake'

    # The only tool we require for building is CMake/Ninja
    required_cli_tools = ['cmake', 'ninja']

    # If we are building an APK we need a few more tools.
    if create_apk:
        if "ANDROID_SDK_ROOT" not in os.environ:
            print("Cannot find ANDROID_SDK_ROOT!")
            sys.exit(1)

        android_sdk_root = os.environ.get('ANDROID_SDK_ROOT')
        print(f"ANDROID_SDK_ROOT = {android_sdk_root}")
        required_cli_tools += ['aapt', 'zipalign', 'keytool', 'apksigner']

    print(f"ANDROID_NDK_HOME = {android_ndk_home}")
    print(f"Build configured for {cmake_config} | {android_stl} | {android_abis} | APK {create_apk}")

    if not os.path.isfile(android_toolchain):
        print(f'Unable to find android.toolchain.cmake at {android_toolchain}')
        exit(-1)

    for tool in required_cli_tools:
        path = shutil.which(tool)
        if path is None:
            print(f"Unable to find {tool}!")
            exit(-1)

        print(f"Using {tool} : {path}")

    cmake_install_dir = RepoRelative('build-android/libs')

    # Delete install directory since it could contain files from old runs
    if os.path.isdir(cmake_install_dir):
        print("Cleaning CMake install")
        shutil.rmtree(cmake_install_dir)

    for abi in android_abis:
        build_dir = RepoRelative(f'build-android/cmake/{abi}')
        lib_dir = f'lib/{abi}'

        if clean:
            print("Deleting CMakeCache.txt")

            # Delete CMakeCache.txt to ensure clean builds
            # NOTE: CMake 3.24 has --fresh which would be better to use in the future.
            cmake_cache = f'{build_dir}/CMakeCache.txt'
            if os.path.isfile(cmake_cache):
                os.remove(cmake_cache)

        cmake_cmd =  f'cmake -S . -B {build_dir} -G Ninja'

        cmake_cmd += f' -D CMAKE_BUILD_TYPE={cmake_config}'
        cmake_cmd += f' -D UPDATE_DEPS=ON -D UPDATE_DEPS_DIR={build_dir}'
        cmake_cmd += f' -D CMAKE_TOOLCHAIN_FILE={android_toolchain}'
        cmake_cmd += f' -D CMAKE_ANDROID_ARCH_ABI={abi}'
        cmake_cmd += f' -D CMAKE_INSTALL_LIBDIR={lib_dir}'
        cmake_cmd += f' -D CMAKE_ANDROID_STL_TYPE={android_stl}'

        cmake_cmd += ' -D ANDROID_PLATFORM=26'
        cmake_cmd += ' -D ANDROID_USE_LEGACY_TOOLCHAIN_FILE=NO'

        RunShellCmd(cmake_cmd)

        build_cmd = f'cmake --build {build_dir}'
        RunShellCmd(build_cmd)

        install_cmd = f'cmake --install {build_dir} --prefix {cmake_install_dir}'
        RunShellCmd(install_cmd)

    if create_apk:
        generate_apk(SDK_ROOT = android_sdk_root, CMAKE_INSTALL_DIR = cmake_install_dir)

if __name__ == '__main__':
    main()
