#!/usr/bin/env python3

# Copyright 2023 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 contextlib
import os
import sys
from string import Template

## Generates `CMakeLists.txt` and `Android.bp`

CMAKE_TEMPLATE_PATH = "template_CMakeLists.txt"
DESTINATION_CMAKELISTS_PATH = "../CMakeLists.txt"

ANDROID_BP_TEMPLATE_PATH = "template_Android.bp"
DESTINATION_ANDROID_BP_PATH = "../Android.bp"

# This custom template class changes the delimiter from '$' to
# '%$%'.
# This is needed because CMake build files use '$' extensively.
class CustomTemplate(Template):
	delimiter = '%$%'

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

# Returns a list of all the .cpp and .c files in the CWD.
def list_all_potentially_compiled_files():
    all_files = []
    for root, sub_folders, files in os.walk("."):
        for file in files:
            file_path = os.path.join(root,file)
            extensions = os.path.splitext(file_path)
            if extensions[1] == ".cpp" or extensions[1] == ".c":
                assert(file_path[0] == '.')
                # Trim the leading '.' out of the path.
                all_files.append(file_path[1:])
    all_files.sort()
    return all_files

# Returns the subset of `files` that do no starts with `banned_prefixes`
def exclude_files_with_prefixes(files, banned_prefixes):
    result = []
    for f in files:
        file_start_with_banned_prefix = False
        for prefix in banned_prefixes:
            if f.startswith(prefix):
                file_start_with_banned_prefix = True
                break
        if not file_start_with_banned_prefix:
            result.append(f)
    return result

# Returns the subset of `files` that starts `needed_prefix`
def keep_files_with_prefix(files, needed_prefix):
    result = []
    for f in files:
        if f.startswith(needed_prefix):
            result.append(f)
    return result

# Get all the files
with pushd("../llvm"):
    all_files = list_all_potentially_compiled_files()

# Split the `all_files`` in several groups
# LLVM common files
prefixes_of_files_not_needed_by_llvm = [
    "/lib/DebugInfo/PDB/DIA/",
    "/lib/ExecutionEngine/OProfileJIT/OProfileWrapper.cpp",
    "/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp",
    "/lib/ExecutionEngine/PerfJITEvents/PerfJITEventListener.cpp",
    "/lib/ExecutionEngine/OProfileJIT",
    "/lib/Frontend/OpenACC/",
    "/lib/MC/MCAsmMacro.cpp",
    "/lib/ObjCopy/",
    "/lib/Support/circular_raw_ostream.cpp",
    "/lib/Support/BLAKE3/",
    "/lib/Support/Locale.cpp",
    "/lib/Target/",
    "/lib/Testing/",
    "/lib/ToolDrivers/llvm-lib/LibDriver.cpp",
    "/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp",
    "/lib/WindowsManifest/WindowsManifestMerger.cpp",
]
files_to_add_back_for_llvm = [
    "/lib/Target/TargetLoweringObjectFile.cpp",
    "/lib/Target/TargetMachine.cpp",
    "/lib/Support/BLAKE3/blake3.c",
    "/lib/Support/BLAKE3/blake3_dispatch.c",
    "/lib/Support/BLAKE3/blake3_portable.c"
]
files_llvm = exclude_files_with_prefixes(all_files, prefixes_of_files_not_needed_by_llvm)
files_llvm.extend(files_to_add_back_for_llvm)

# Architecture specific files
files_x86 = keep_files_with_prefix(all_files, "/lib/Target/X86/")
files_Mips = keep_files_with_prefix(all_files, "/lib/Target/Mips/")
files_AArch64 = keep_files_with_prefix(all_files, "/lib/Target/AArch64/")
files_ARM = keep_files_with_prefix(all_files, "/lib/Target/ARM/")
files_PowerPC = keep_files_with_prefix(all_files, "/lib/Target/PowerPC/")
files_RISCV = keep_files_with_prefix(all_files, "/lib/Target/RISCV/")

generated_file_comment = "File generated by " + sys.argv[0]

# Generate CMakeLists.txt
def format_file_list_for_cmake(files):
    return '\n'.join(["        ${LLVM_DIR}" + s for s in files])
cmake_template_data = {
    'generated_file_comment' : "# " + generated_file_comment,
    'files_llvm' : '\n'.join(["    ${LLVM_DIR}" + s for s in files_llvm]),
    'files_x86' : format_file_list_for_cmake(files_x86),
    'files_Mips' : format_file_list_for_cmake(files_Mips),
    'files_AArch64' : format_file_list_for_cmake(files_AArch64),
    'files_ARM' : format_file_list_for_cmake(files_ARM),
    'files_PowerPC' : format_file_list_for_cmake(files_PowerPC),
    'files_RISCV' : format_file_list_for_cmake(files_RISCV),
}
with open(CMAKE_TEMPLATE_PATH, 'r') as f:
    cmake_template = CustomTemplate(f.read())
    result = cmake_template.substitute(cmake_template_data)
    cmake_output = open(DESTINATION_CMAKELISTS_PATH, "w")
    cmake_output.write(result)

# Generate Android.bp
def format_file_list_for_android_bp(files):
    return '\n'.join(["        \"llvm" + s + "\"," for s in files])
android_bp_template_data = {
    'generated_file_comment' : "// " + generated_file_comment,
    'files_llvm' : format_file_list_for_android_bp(files_llvm),
    'files_x86' : format_file_list_for_android_bp(files_x86),
    'files_AArch64' : format_file_list_for_android_bp(files_AArch64),
    'files_ARM' : format_file_list_for_android_bp(files_ARM),
    'files_RISCV' : format_file_list_for_android_bp(files_RISCV),
}
with open(ANDROID_BP_TEMPLATE_PATH, 'r') as f:
    android_bp_template = CustomTemplate(f.read())
    result = android_bp_template.substitute(android_bp_template_data)
    cmake_output = open(DESTINATION_ANDROID_BP_PATH, "w")
    cmake_output.write(result)
