#!/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.
#
from __future__ import print_function

import argparse
import glob
import multiprocessing
import os
import shutil
import subprocess
import sys
import re


THIS_DIR = os.path.realpath(os.path.dirname(__file__))
ORIG_ENV = dict(os.environ)


def android_path(*args):
    out_dir = os.path.realpath(os.path.join(THIS_DIR, '../..', *args))
    return out_dir


def build_path(*args):
    # Our multistage build directories will be placed under OUT_DIR if it is in
    # the environment. By default they will be placed under
    # $ANDROID_BUILD_TOP/out.
    top_out = ORIG_ENV.get('OUT_DIR', android_path('out'))
    if not os.path.isabs(top_out):
        top_out = os.path.realpath(top_out)
    out_dir = os.path.join(top_out, *args)
    return out_dir


def install_file(src, dst):
    print('Copying ' + src)
    shutil.copy2(src, dst)


def install_directory(src, dst):
    print('Copying ' + src)
    shutil.copytree(src, dst)


def build(out_dir):
    products = (
        'aosp_arm',
        'aosp_arm64',
        # 'aosp_mips',
        # 'aosp_mips64',
        'aosp_x86',
        'aosp_x86_64',
    )
    for product in products:
        build_product(out_dir, product)


def build_product(out_dir, product):
    env = dict(ORIG_ENV)
    env['FORCE_BUILD_LLVM_COMPONENTS'] = 'true'
    env['FORCE_BUILD_RS_COMPAT'] = 'true'
    env['OUT_DIR'] = out_dir
    env['SKIP_LLVM_TESTS'] = 'true'
    env['SOONG_ALLOW_MISSING_DEPENDENCIES'] = 'true'
    env['TARGET_BUILD_VARIANT'] = 'userdebug'
    env['TARGET_PRODUCT'] = product

    jobs_arg = '-j{}'.format(multiprocessing.cpu_count())
    targets = [
        # PHONY target specified in frameworks/rs/Android.mk.
        'rs-prebuilts-full',
        # We have to explicitly specify the jar for JACK to build.
        android_path('out/target/common/obj/JAVA_LIBRARIES/' +
            'android-support-v8-renderscript_intermediates/classes.jar')
    ]
    subprocess.check_call(
        ['make', jobs_arg] + targets, cwd=android_path(), env=env)


def package_toolchain(build_dir, build_name, host, dist_dir):
    package_name = 'renderscript-' + build_name
    install_host_dir = build_path('install', host)
    install_dir = os.path.join(install_host_dir, package_name)

    # Remove any previously installed toolchain so it doesn't pollute the
    # build.
    if os.path.exists(install_host_dir):
        shutil.rmtree(install_host_dir)

    install_toolchain(build_dir, install_dir, host)

    tarball_name = package_name + '-' + host
    package_path = os.path.join(dist_dir, tarball_name) + '.tar.bz2'
    print('Packaging ' + package_path)
    args = [
        'tar', '-cjC', install_host_dir, '-f', package_path, package_name
    ]
    subprocess.check_call(args)


def install_toolchain(build_dir, install_dir, host):
    install_built_host_files(build_dir, install_dir, host)
    install_clang_headers(build_dir, install_dir, host)
    install_built_device_files(build_dir, install_dir, host)
    install_license_files(install_dir)
    # We need to package libwinpthread-1.dll for Windows. This is explicitly
    # linked whenever pthreads is used, and the build system doesn't allow
    # us to link just that library statically (ldflags are stripped out
    # of ldlibs and vice-versa).
    # Bug: http://b/34273721
    if host.startswith('windows'):
        install_winpthreads(install_dir)


def install_winpthreads(install_dir):
      """Installs the winpthreads runtime to the Windows bin directory."""
      lib_name = 'libwinpthread-1.dll'
      mingw_dir = android_path(
          'prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8')
      # RenderScript NDK toolchains for Windows only contains 32-bit binaries.
      lib_path = os.path.join(mingw_dir, 'x86_64-w64-mingw32/lib32', lib_name)

      lib_install = os.path.join(install_dir, 'bin', lib_name)
      install_file(lib_path, lib_install)


def install_built_host_files(build_dir, install_dir, host):
    is_windows = host.startswith('windows')
    is_darwin = host.startswith('darwin-x86')
    bin_ext = '.exe' if is_windows else ''

    if is_windows:
        lib_ext = '.dll'
    elif is_darwin:
        lib_ext = '.dylib'
    else:
        lib_ext = '.so'

    built_files = [
        'bin/llvm-rs-cc' + bin_ext,
        'bin/bcc_compat' + bin_ext,
    ]

    if is_windows:
        built_files.extend([
            'lib/libbcc' + lib_ext,
            'lib/libbcinfo' + lib_ext,
            'lib/libclang' + lib_ext,
            'lib/libLLVM' + lib_ext,
        ])
    else:
        built_files.extend([
            'lib64/libbcc' + lib_ext,
            'lib64/libbcinfo' + lib_ext,
            'lib64/libclang' + lib_ext,
            'lib64/libLLVM' + lib_ext,
            'lib64/libc++' + lib_ext,
            'lib64/libclang_android' + lib_ext,
            'lib64/libLLVM_android' + lib_ext,
        ])

    for built_file in built_files:
        dirname = os.path.dirname(built_file)
        # Put dlls and exes into bin/ for windows.
        # Bug: http://b/34273721
        if is_windows:
            dirname = 'bin'
        install_path = os.path.join(install_dir, dirname)
        if not os.path.exists(install_path):
            os.makedirs(install_path)

        built_path = os.path.join(build_dir, 'host', host, built_file)
        install_file(built_path, install_path)

        file_name = os.path.basename(built_file)

        # Only strip bin files (not libs) on darwin.
        if not is_darwin or built_file.startswith('bin/'):
            subprocess.check_call(
                ['strip', os.path.join(install_path, file_name)])


def install_clang_headers(build_dir, install_dir, host):
    def should_copy(path):
        if os.path.basename(path) in ('Makefile', 'CMakeLists.txt'):
            return False
        _, ext = os.path.splitext(path)
        if ext == '.mk':
            return False
        return True

    headers_src = android_path('external/clang/lib/Headers')
    headers_dst = os.path.join(
        install_dir, 'clang-include')
    os.makedirs(headers_dst)
    for header in os.listdir(headers_src):
        if not should_copy(header):
            continue
        install_file(os.path.join(headers_src, header), headers_dst)

    install_file(android_path('bionic/libc/include/stdatomic.h'), headers_dst)


def install_built_device_files(build_dir, install_dir, host):
    product_to_arch = {
        'generic': 'arm',
        'generic_arm64': 'arm64',
        'generic_mips': 'mips',
        # 'generic_mips64': 'mips64el',
        'generic_x86': 'x86',
        'generic_x86_64': 'x86_64',
    }

    bc_lib = 'librsrt'

    static_libs = {
        'libRScpp_static',
        'libcompiler_rt'
    }

    shared_libs = {
        'libRSSupport',
        'libRSSupportIO',
        'libblasV8',
    }

    for product, arch in product_to_arch.items():
        lib_dir = os.path.join(install_dir, 'platform', arch)
        os.makedirs(lib_dir)

        # Copy librsrt_ARCH.bc.
        lib_name = bc_lib + '_' + arch + '.bc'
        if not host.startswith('windows'):
            built_lib = os.path.join(build_dir, 'host', host, 'lib64', lib_name)
        else:
            built_lib = os.path.join(build_dir, 'host', 'linux-x86', 'lib64', lib_name)
        install_file(built_lib, os.path.join(lib_dir, bc_lib + '.bc'))

        # Copy static libs and share libs.
        product_dir = os.path.join(build_dir, 'target/product', product)
        static_lib_dir = os.path.join(product_dir, 'obj/STATIC_LIBRARIES')
        shared_lib_dir = os.path.join(product_dir, 'obj/SHARED_LIBRARIES')
        for static_lib in static_libs:
            built_lib = os.path.join(
                static_lib_dir, static_lib + '_intermediates/' + static_lib + '.a')
            lib_name = static_lib + '.a'
            install_file(built_lib, os.path.join(lib_dir, lib_name))
        for shared_lib in shared_libs:
            built_lib = os.path.join(
                shared_lib_dir, shared_lib + '_intermediates/' + shared_lib + '.so')
            lib_name = shared_lib + '.so'
            install_file(built_lib, os.path.join(lib_dir, lib_name))

    # Copy renderscript-v8.jar.
    lib_dir = os.path.join(install_dir, 'platform')
    jar_dir = os.path.join(build_dir, 'target/common/obj/JAVA_LIBRARIES/'
        'android-support-v8-renderscript_intermediates/classes.jar')
    install_file(jar_dir, os.path.join(lib_dir, 'renderscript-v8.jar'))

    # Copy RS runtime headers.
    headers_dst_base = os.path.join(install_dir, 'platform', 'rs')

    headers_src = android_path('frameworks/rs/script_api/include')
    headers_dst = os.path.join(headers_dst_base, 'scriptc')
    install_directory(headers_src, headers_dst)

    # Copy RS C++ API headers.
    headers_src = android_path('frameworks/rs/cpp/util')
    headers_dst = os.path.join(headers_dst_base, 'cpp/util')
    install_directory(headers_src, headers_dst)
    install_file(android_path('frameworks/rs/rsDefines.h'), headers_dst_base)
    install_file(android_path('frameworks/rs/cpp/RenderScript.h'), os.path.join(headers_dst_base, 'cpp'))
    install_file(android_path('frameworks/rs/cpp/rsCppStructs.h'), os.path.join(headers_dst_base, 'cpp'))


def install_license_files(install_dir):
    projects = (
        'external/clang',
        'external/compiler-rt',
        'external/llvm',
        'frameworks/compile/slang',
        'frameworks/compile/libbcc',
        # 'frameworks/rs', # No notice license file found.
    )

    notices = []
    for project in projects:
        project_path = android_path(project)
        license_pattern = os.path.join(project_path, 'MODULE_LICENSE_*')
        for license_file in glob.glob(license_pattern):
            install_file(license_file, install_dir)
        with open(os.path.join(project_path, 'NOTICE')) as notice_file:
            notices.append(notice_file.read())
    with open(os.path.join(install_dir, 'NOTICE'), 'w') as notice_file:
        notice_file.write('\n'.join(notices))


def parse_args():
    parser = argparse.ArgumentParser()

    parser.add_argument(
        '--build-name', default='dev', help='Release name for the package.')

    return parser.parse_args()


def main():
    args = parse_args()

    if sys.platform.startswith('linux'):
        hosts = ['linux-x86', 'windows-x86']
    elif sys.platform == 'darwin':
        hosts = ['darwin-x86']
    else:
        raise RuntimeError('Unsupported host: {}'.format(sys.platform))

    out_dir = build_path()
    build(out_dir=out_dir)

    dist_dir = ORIG_ENV.get('DIST_DIR', out_dir)
    for host in hosts:
        package_toolchain(out_dir, args.build_name, host, dist_dir)


if __name__ == '__main__':
    main()
