#!/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`.

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

# 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/ObjCopy/",
    "/lib/Support/BLAKE3/",
    "/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/")

# Generate CMakeLists.txt
cmake_template_data = {
    'generated_file_comment' : "# File generated by " + sys.argv[0],
    'files_llvm' : '\n'.join(["    ${LLVM_DIR}" + s for s in files_llvm]),
    'files_x86' : '\n'.join(["        ${LLVM_DIR}" + s for s in files_x86]),
    'files_Mips' : '\n'.join(["        ${LLVM_DIR}" + s for s in files_Mips]),
    'files_AArch64' : '\n'.join(["        ${LLVM_DIR}" + s for s in files_AArch64]),
    'files_ARM' : '\n'.join(["        ${LLVM_DIR}" + s for s in files_ARM]),
    'files_PowerPC' : '\n'.join(["        ${LLVM_DIR}" + s for s in files_PowerPC]),
    'files_RISCV' : '\n'.join(["        ${LLVM_DIR}" + s for s in 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)
