#!/usr/bin/env python3

# Copyright 2018 The SwiftShader 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.

import argparse
import contextlib
import multiprocessing
import os
import platform
import re
import shutil
import subprocess
import sys
import tempfile
from os import path

# LLVM_BRANCH must match the value of the same variable in third_party/update-llvm-10.sh
LLVM_BRANCH = "release/10.x"

# LLVM_COMMIT must be set to the commit hash that we last updated to when running third_party/update-llvm-10.sh.
# Run 'git show -s origin/llvm10-clean' and look for 'llvm-10-update: <hash>' to retrieve it.
LLVM_COMMIT = "d32170dbd5b0d54436537b6b75beaf44324e0c28"

SCRIPT_DIR = path.dirname(path.realpath(sys.argv[0]))
LLVM_STAGING_DIR = path.abspath(path.join(tempfile.gettempdir(), "llvm-10"))
LLVM_DIR = path.abspath(path.join(LLVM_STAGING_DIR, "llvm"))
LLVM_OBJS = path.join(LLVM_STAGING_DIR, "build")
LLVM_CONFIGS = path.abspath(path.join(SCRIPT_DIR, '..', 'configs'))

# List of all arches SwiftShader supports
LLVM_TARGETS = [
    ('AArch64', ('__aarch64__',)),
    ('ARM', ('__arm__',)),
    ('X86', ('__i386__', '__x86_64__')),
    ('Mips', ('__mips__',)),
    ('PowerPC', ('__powerpc64__',)),
]

# Per-platform arches
LLVM_TRIPLES = {
    'android': [
        ('__x86_64__', 'x86_64-linux-android'),
        ('__i386__', 'i686-linux-android'),
        ('__arm__', 'armv7-linux-androideabi'),
        ('__aarch64__', 'aarch64-linux-android'),
    ],
    'linux': [
        ('__x86_64__', 'x86_64-unknown-linux-gnu'),
        ('__i386__', 'i686-pc-linux-gnu'),
        ('__arm__', 'armv7-linux-gnueabihf'),
        ('__aarch64__', 'aarch64-linux-gnu'),
        ('__mips__', 'mipsel-linux-gnu'),
        ('__mips64', 'mips64el-linux-gnuabi64'),
        ('__powerpc64__', 'powerpc64le-unknown-linux-gnu'),
    ],
    'darwin': [
        ('__x86_64__', 'x86_64-apple-darwin'),
        ('__aarch64__', 'arm64-apple-darwin'),
    ],
    'windows': [
        ('__x86_64__', 'x86_64-pc-win32'),
        ('__i386__', 'i686-pc-win32'),
        ('__arm__', 'armv7-pc-win32'),
        ('__aarch64__', 'aarch64-pc-win32'),
        ('__mips__', 'mipsel-pc-win32'),
        ('__mips64', 'mips64el-pc-win32'),
    ],
}

# Mapping of target platform to the host it must be built on
LLVM_PLATFORM_TO_HOST_SYSTEM = {
    'android': 'Linux',
    'darwin': 'Darwin',
    'linux': 'Linux',
    'windows': 'Windows',
}

# LLVM configurations to be undefined.
LLVM_UNDEF_MACROS = [
    'BACKTRACE_HEADER',
    'ENABLE_BACKTRACES',
    'ENABLE_CRASH_OVERRIDES',
    'HAVE_BACKTRACE',
    'HAVE_POSIX_SPAWN',
    'HAVE_PTHREAD_GETNAME_NP',
    'HAVE_PTHREAD_SETNAME_NP',
    'HAVE_TERMIOS_H',
    'HAVE_ZLIB_H',
    'HAVE__UNWIND_BACKTRACE',
]

# General CMake options for building LLVM
LLVM_CMAKE_OPTIONS = [
    '-DCMAKE_BUILD_TYPE=Release',
    '-DLLVM_ENABLE_THREADS=ON',
    '-DLLVM_ENABLE_TERMINFO=OFF',
    '-DLLVM_ENABLE_LIBXML2=OFF',
    '-DLLVM_ENABLE_LIBEDIT=OFF',
    '-DLLVM_ENABLE_LIBPFM=OFF',
    '-DLLVM_ENABLE_ZLIB=OFF',
    '-DLLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN=ON'
]


@contextlib.contextmanager
def pushd(new_dir):
    previous_dir = os.getcwd()
    os.chdir(new_dir)
    try:
        yield
    finally:
        os.chdir(previous_dir)


def log(message, level=1):
    print(' ' * level + '> ' + message)


def run_command(command, log_level=1):
    log(command, log_level)
    os.system(command)


def run_subprocess(*popenargs, log_level=1, cwd=None):
    log([' '.join(t) for t in popenargs][0], log_level)
    return subprocess.run(*popenargs, cwd=cwd)


def _parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('name', help='destination name',
                        choices=['android', 'linux', 'darwin', 'windows'])
    parser.add_argument('-j', '--jobs', help='parallel compilation', type=int)
    return parser.parse_args()


def validate_args(args):
    host = platform.system()
    if host not in LLVM_PLATFORM_TO_HOST_SYSTEM.values():
        raise Exception(f"Host system not supported: '{host}'")

    if args.name not in LLVM_PLATFORM_TO_HOST_SYSTEM.keys():
        raise Exception(f"Unknown target platform: '{args.name}'")

    expected_host = LLVM_PLATFORM_TO_HOST_SYSTEM[args.name]
    if LLVM_PLATFORM_TO_HOST_SYSTEM[args.name] != host:
        raise Exception(
            f"Target platform '{args.name}' must be built on '{expected_host}', not on '{host}'")


def get_cmake_targets_to_build(platform):
    """Returns list of LLVM targets to build for the input platform"""
    targets = set()
    for arch_def, triplet in LLVM_TRIPLES[platform]:
        for arch, defs in LLVM_TARGETS:
            if arch_def in defs:
                targets.add(arch)

    # Maintain the sort order of LLVM_TARGETS as this affects how config
    # headers are generated
    return [t[0] for t in LLVM_TARGETS if t[0] in targets]


def clone_llvm():
    log("Cloning/Updating LLVM", 1)
    # Clone or update staging directory
    if not path.exists(LLVM_STAGING_DIR):
        os.mkdir(LLVM_STAGING_DIR)
        with pushd(LLVM_STAGING_DIR):
            run_command('git init', 2)
            run_command(
                'git remote add origin https://github.com/llvm/llvm-project.git', 2)
            run_command('git config core.sparsecheckout true', 2)
            run_command('echo /llvm > .git/info/sparse-checkout', 2)

    with pushd(LLVM_STAGING_DIR):
        run_command('echo /llvm > .git/info/sparse-checkout', 2)
        run_command('git fetch origin {}'.format(LLVM_BRANCH), 2)
        run_command('git checkout {}'.format(LLVM_COMMIT), 2)
    return


def build_llvm(name, num_jobs):
    """Build LLVM and get all generated files."""
    log("Building LLVM", 1)
    if num_jobs is None:
        num_jobs = multiprocessing.cpu_count()

    """On Windows we need to have CMake generate build files for the 64-bit
    Visual Studio host toolchain."""
    host = '-Thost=x64' if name == 'windows' else ''

    cmake_options = LLVM_CMAKE_OPTIONS + ['-DLLVM_TARGETS_TO_BUILD=' +
                                          ';'.join(t for t in get_cmake_targets_to_build(name))]

    os.makedirs(LLVM_OBJS, exist_ok=True)
    run_subprocess(['cmake', host, LLVM_DIR] +
                   cmake_options, log_level=2, cwd=LLVM_OBJS)
    run_subprocess(['cmake', '--build', '.', '-j',
                    str(num_jobs)], log_level=2, cwd=LLVM_OBJS)


def list_files(src_base, src, dst_base, suffixes):
    """Enumerate the files that are under `src` and end with one of the
    `suffixes` and yield the source path and the destination path."""
    src_base = path.abspath(src_base)
    src = path.join(src_base, src)
    for base_dir, dirnames, filenames in os.walk(src):
        for filename in filenames:
            if path.splitext(filename)[1] in suffixes:
                relative = path.relpath(base_dir, src_base)
                yield (path.join(base_dir, filename),
                       path.join(dst_base, relative, filename))


def copy_common_generated_files(dst_base):
    """Copy platform-independent generated files."""
    log("Copying platform-independent generated files", 1)
    suffixes = {'.inc', '.h', '.def'}
    subdirs = [
        path.join('include', 'llvm', 'IR'),
        path.join('include', 'llvm', 'Support'),
        path.join('lib', 'IR'),
        path.join('lib', 'Transforms', 'InstCombine'),
    ] + [path.join('lib', 'Target', arch) for arch, defs in LLVM_TARGETS]
    for subdir in subdirs:
        for src, dst in list_files(LLVM_OBJS, subdir, dst_base, suffixes):
            log('{} -> {}'.format(src, dst), 2)
            os.makedirs(path.dirname(dst), exist_ok=True)
            shutil.copyfile(src, dst)


def copy_platform_file(platform, src, dst):
    """Copy platform-dependent generated files and add platform-specific
    modifications."""

    # LLVM configuration patterns to be post-processed.
    llvm_target_pattern = re.compile('^LLVM_[A-Z_]+\\(([A-Za-z0-9_]+)\\)$')
    llvm_native_pattern = re.compile(
        '^#define LLVM_NATIVE_([A-Z]+) (LLVMInitialize)?(.*)$')
    llvm_triple_pattern = re.compile('^#define (LLVM_[A-Z_]+_TRIPLE) "(.*)"$')
    llvm_define_pattern = re.compile('^#define ([A-Za-z0-9_]+) (.*)$')

    # Build architecture-specific conditions.
    conds = {}
    for arch, defs in LLVM_TARGETS:
        conds[arch] = ' || '.join('defined(' + v + ')' for v in defs)

    # Get a set of platform-specific triples.
    triples = LLVM_TRIPLES[platform]

    with open(src, 'r') as src_file:
        os.makedirs(path.dirname(dst), exist_ok=True)
        with open(dst, 'w') as dst_file:
            for line in src_file:
                if line == '#define LLVM_CONFIG_H\n':
                    print(line, file=dst_file, end='')
                    print('', file=dst_file)
                    print('#if !defined(__i386__) && defined(_M_IX86)',
                          file=dst_file)
                    print('#define __i386__ 1', file=dst_file)
                    print('#endif', file=dst_file)
                    print('', file=dst_file)
                    print(
                        '#if !defined(__x86_64__) && (defined(_M_AMD64) || defined (_M_X64))', file=dst_file)
                    print('#define __x86_64__ 1', file=dst_file)
                    print('#endif', file=dst_file)
                    print('', file=dst_file)

                match = llvm_target_pattern.match(line)
                if match:
                    arch = match.group(1)
                    print('#if ' + conds[arch], file=dst_file)
                    print(line, file=dst_file, end='')
                    print('#endif', file=dst_file)
                    continue

                match = llvm_native_pattern.match(line)
                if match:
                    name = match.group(1)
                    init = match.group(2) or ''
                    arch = match.group(3)
                    end = ''
                    if arch.lower().endswith(name.lower()):
                        end = arch[-len(name):]
                    directive = '#if '
                    for arch, defs in LLVM_TARGETS:
                        print(directive + conds[arch], file=dst_file)
                        print('#define LLVM_NATIVE_' + name + ' ' +
                              init + arch + end, file=dst_file)
                        directive = '#elif '
                    print('#else', file=dst_file)
                    print('#error "unknown architecture"', file=dst_file)
                    print('#endif', file=dst_file)
                    continue

                match = llvm_triple_pattern.match(line)
                if match:
                    name = match.group(1)
                    directive = '#if'
                    for defs, triple in triples:
                        print(directive + ' defined(' + defs + ')',
                              file=dst_file)
                        print('#define ' + name + ' "' + triple + '"',
                              file=dst_file)
                        directive = '#elif'
                    print('#else', file=dst_file)
                    print('#error "unknown architecture"', file=dst_file)
                    print('#endif', file=dst_file)
                    continue

                match = llvm_define_pattern.match(line)
                if match and match.group(1) in LLVM_UNDEF_MACROS:
                    print('/* #undef ' + match.group(1) + ' */', file=dst_file)
                    continue

                print(line, file=dst_file, end='')


def copy_platform_generated_files(platform, dst_base):
    """Copy platform-specific generated files."""
    log("Copying platform-specific generated files", 1)
    suffixes = {'.inc', '.h', '.def'}
    src_dir = path.join('include', 'llvm', 'Config')
    for src, dst in list_files(LLVM_OBJS, src_dir, dst_base, suffixes):
        log('{}, {} -> {}'.format(platform, src, dst), 2)
        copy_platform_file(platform, src, dst)


def main():
    args = _parse_args()
    validate_args(args)
    clone_llvm()
    build_llvm(args.name, args.jobs)
    copy_common_generated_files(path.join(LLVM_CONFIGS, 'common'))
    copy_platform_generated_files(
        args.name, path.join(LLVM_CONFIGS, args.name))


if __name__ == '__main__':
    main()
