import os
import sys
import platform
import argparse

from setuptools import setup, Extension
from Cython.Build import cythonize


def print_error(*s: str):
    print("\033[91m {}\033[00m".format(' '.join(s)))


def print_succes(*s: str):
    print("\033[92m {}\033[00m".format(' '.join(s)))


def print_info(*s: str):
    print("\033[93m {}\033[00m".format(' '.join(s)))


def main(debug: bool):

    print_info("\nBuilding WBS kernel...")
    print(f"Target mode: {'Debug' if debug else 'Release'}")


    if platform.system() == 'Darwin':
        if debug:
            extra_compile_args = ['-std=c++17', '-g3', '-O0']
            extra_link_args = []
        else:
            extra_compile_args = ['-std=c++17', '-O3']
            extra_link_args = []

    elif platform.system() == 'Windows':
        if debug:
            extra_compile_args = ['/std:c++17', '/Zi', '/Od']
            extra_link_args = ['/DEBUG:FULL']
        else:
            extra_compile_args = ['/std:c++17']
            extra_link_args = []
    else:
        if debug:
            extra_compile_args = ['-std=c++17', '-O0', '-g']
            extra_link_args = []
        else:
            extra_compile_args = ['-std=c++17', '-O3']
            extra_link_args = []

    common_include_dirs = [
        "src/bl_src/source/blender/blenkernel/",
        "src/bl_src/source/blender/blenlib/",
        "src/bl_src/source/blender/makesdna/",
        "src/bl_src/source/blender/makesrna/",
        "src/bl_src/intern/guardedalloc/",
        "src/"
    ]

    wmo_utils_sources = [
        "src/wmo_utils.pyx",
        "src/bl_utils/math_utils.cpp",
        "src/bl_utils/color_utils.cpp",
        "src/bl_utils/mesh/custom_data.cpp",
        "src/bl_utils/mesh/wmo/batch_geometry.cpp",
        "src/bl_utils/mesh/wmo/bsp_tree.cpp",
        "src/bl_utils/mesh/wmo/wmo_liquid_exporter.cpp"
    ]

    wmo_utils_include_dirs = [
        "src/bl_utils",
        "src/bl_utils/mesh",
        "src/bl_utils/wmo"
    ]

    sources = wmo_utils_sources
    include_dirs = common_include_dirs + wmo_utils_include_dirs

    formatted_includes = '\n'.join([f"${{CMAKE_SOURCE_DIR}}/{include_dir}" for include_dir in include_dirs])
    formatted_sources = '\n'.join([f"${{CMAKE_SOURCE_DIR}}/{source_file}"
                        for source_file in filter(lambda x: os.path.splitext(x)[1] in ('.hpp', '.cpp', 'inl'), sources)])

    cmake_stub = \
        f"""
        \n# This file is an autogenerated cmake stub for development purposes, not for building wbs_kernel.
        \ncmake_minimum_required(VERSION 3.15)

        \nproject(wbs_kernel VERSION 0.1)
        \nset(CMAKE_CXX_STANDARD 17)
        \nset(CMAKE_CXX_STANDARD_REQUIRED ON)
        \nset(CMAKE_CXX_FLAGS_DEBUG "${{CMAKE_CXX_FLAGS_DEBUG}} -O0")

        \ninclude_directories(
          \n{formatted_includes}
        \n)

        \nadd_library(wbs_kernel
          \n{formatted_sources}
        \n)

        \nset_target_properties(wbs_kernel PROPERTIES PREFIX "" OUTPUT_NAME "wbs_kernel<$<CONFIG:Debug>:d>")
        """

    with open('CMakeLists.txt', 'w') as f:
        f.write(cmake_stub)

    setup(
        name='WBS kernel : wmo_utils',
        ext_modules=cythonize([
            Extension(
                "wmo_utils",
                sources=wmo_utils_sources,
                include_dirs=wmo_utils_include_dirs + common_include_dirs,
                language="c++",
                extra_compile_args=extra_compile_args,
                extra_link_args=extra_link_args
            )]
        ),
        requires=['Cython'])

    print_succes("\nSuccessfully built WBS kernel.")


if __name__ == '__main__':

    parser = argparse.ArgumentParser()
    parser.add_argument('--wbs_debug', action='store_true', help='Compile WBS kernel in debug mode.')
    args, unknown = parser.parse_known_args()

    if args.wbs_debug:
        sys.argv.remove('--wbs_debug')

    main(args.wbs_debug)
