#!/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'),
    ],
    '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()
