# SCub for building the Godot Cesium submodule
import CesiumBuildUtils as cesium_build_utils
import os

Import("env")

cesium_env = env.Clone()


def load_cesium_module(p_includePaths: list[str], moduleName: str, loadSources=False, rootDir=""):
    if (rootDir == ""):
        rootDir = cesium_build_utils.get_root_dir_native()
    base_include = "%s/%s/include" % (rootDir, moduleName)
    generated_include = "%s/%s/generated/include" % (rootDir, moduleName)
    p_includePaths.append(cesium_build_utils.scons_to_abs_path(base_include))
    p_includePaths.append(cesium_build_utils.scons_to_abs_path(generated_include))


env.Append(CPPDEFINES=[("_HAS_EXCEPTIONS", 1)])
if os.name == cesium_build_utils.OS_WIN:
    env.Append(CXXFLAGS=["/EHsc"])
env.Append(CPPDEFINES=["SPDLOG_NO_EXCEPTIONS",
                       "LIBASYNC_NO_EXCEPTIONS"])

includePaths = []
sources = [
    cesium_build_utils.get_root_dir() + "/register_types.cpp",
    cesium_build_utils.get_root_dir() + "/Models/CesiumGDTileset.cpp",
    cesium_build_utils.get_root_dir() + "/Models/Cesium3DTile.cpp",
    cesium_build_utils.get_root_dir() + "/Models/TileMetadata.cpp",
    cesium_build_utils.get_root_dir() + "/Models/CesiumGDPanel.cpp",
    cesium_build_utils.get_root_dir() + "/Models/CesiumGDRasterOverlay.cpp",
    cesium_build_utils.get_root_dir() + "/Models/CesiumGlobe.cpp",
    cesium_build_utils.get_root_dir() + "/Models/CesiumGDConfig.cpp",
    cesium_build_utils.get_root_dir() + "/Models/CesiumHTTPRequestNode.cpp",
    cesium_build_utils.get_root_dir() + "/Models/CesiumGDCreditSystem.cpp",
    cesium_build_utils.get_root_dir() + "/Implementations/NetworkAssetAccessor.cpp",
    cesium_build_utils.get_root_dir() + "/Implementations/DocumentContainer.cpp",
    cesium_build_utils.get_root_dir() + "/Implementations/GodotPrepareRenderResources.cpp",
    cesium_build_utils.get_root_dir() + "/CesiumGDModelLoader.cpp",
    cesium_build_utils.get_root_dir() + "/Utils/CesiumGDTextureLoader.cpp",
    cesium_build_utils.get_root_dir() + "/Utils/CesiumDebugUtils.cpp",
    cesium_build_utils.get_root_dir() + "/Utils/AssetManipulation.cpp",
    cesium_build_utils.get_root_dir() + "/Utils/CesiumGDAssetBuilder.cpp",
    cesium_build_utils.get_root_dir() + "/Utils/TokenTroubleShooting.cpp"
]


load_cesium_module(includePaths, "Cesium3DTiles")
load_cesium_module(includePaths, "Cesium3DTilesContent")
load_cesium_module(includePaths, "Cesium3DTilesReader")
load_cesium_module(includePaths, "Cesium3DTilesSelection")
load_cesium_module(includePaths, "Cesium3DTilesWriter")
load_cesium_module(includePaths, "CesiumAsync")
load_cesium_module(includePaths, "CesiumGeometry")
load_cesium_module(includePaths, "CesiumGeospatial")
load_cesium_module(includePaths, "CesiumGltf")
load_cesium_module(includePaths, "CesiumGltfContent")
load_cesium_module(includePaths, "CesiumGltfReader")
load_cesium_module(includePaths, "CesiumGltfWriter")
load_cesium_module(includePaths, "CesiumIonClient")
load_cesium_module(includePaths, "CesiumJsonReader")
load_cesium_module(includePaths, "CesiumJsonWriter")
load_cesium_module(includePaths, "CesiumNativeTests")
load_cesium_module(includePaths, "CesiumQuantizedMeshTerrain")
load_cesium_module(includePaths, "CesiumRasterOverlays")
load_cesium_module(includePaths, "CesiumUtility")
load_cesium_module(includePaths, "extern/gsl")
load_cesium_module(includePaths, "extern/asyncplusplus")
load_cesium_module(includePaths, "extern/fmt")
load_cesium_module(includePaths, "extern/spdlog")
load_cesium_module(includePaths, "extern/glm")
load_cesium_module(includePaths, "extern/draco")
load_cesium_module(includePaths, "extern/modp")
load_cesium_module(includePaths, "extern/rapidjson")
load_cesium_module(includePaths, "extern/KHR")
load_cesium_module(includePaths, "extern/webp")
load_cesium_module(includePaths, "extern/misc")
load_cesium_module(includePaths, "extern/nonstd")
load_cesium_module(includePaths, "extern/s2")
load_cesium_module(includePaths, "curl",
                   rootDir=cesium_build_utils.get_root_dir() + "/third_party")
load_cesium_module(includePaths, "litehtml",
                   rootDir=cesium_build_utils.get_root_dir() + "/third_party")

if (cesium_build_utils.is_extension_target(ARGUMENTS)):
    cesium_env.add_source_files(sources)
else:
    cesium_env.add_source_files(cesium_env.modules_sources, sources)

vcpkgIncludePath = cesium_build_utils.find_ezvcpkg_include_path()
includePaths.append(vcpkgIncludePath)

env.Append(CPPPATH=includePaths)


root_dir_native = cesium_build_utils.get_root_dir_native()
current_build_config = ""
if (os.name  == cesium_build_utils.OS_WIN):
    current_build_config = cesium_build_utils.RELEASE_CONFIG
# Library paths and linking
libraries = [
    "Cesium3DTilesSelection",
    "CesiumRasterOverlays",
    "Cesium3DTilesContent",
    "Cesium3DTilesReader",
    "CesiumGltfReader",
    "CesiumGltf",
    "CesiumAsync",
    "CesiumJsonReader",
    "CesiumUtility",
    "CesiumGeospatial",
    "CesiumGeometry",
    "CesiumGltfContent",
    "CesiumQuantizedMeshTerrain",
    "async++",
    "ktx",
    # "astcenc-avx2-static",
    "jpeg",
    "turbojpeg",
    "draco",
    "uriparser",
    "s2",
    "glm",
    "fmt",
    "spdlog",
    "tinyxml2",
    cesium_build_utils.get_curl_lib_name(),
    "sqlite3",
    # Needed only for GDExtension as it appears godot already links this
    "libwebp",
    "libwebpdecoder",
    "zstd",
    "libssl",
    "meshoptimizer",
    "ada",
    "litehtml", # 35ecd69d05e72b0148204a576db62c2148084193
    "gumbo"
]

if (os.name == cesium_build_utils.OS_WIN):
    libraries.extend([
        "absl_bad_any_cast_impl",
        "absl_bad_optional_access",
        "absl_bad_variant_access",
        "absl_base",
        "absl_city",
        "absl_civil_time",
        "absl_cord",
        "absl_cordz_functions",
        "absl_cordz_handle",
        "absl_cordz_info",
        "absl_cordz_sample_token",
        "absl_cord_internal",
        "absl_crc32c",
        "absl_crc_cord_state",
        "absl_crc_cpu_detect",
        "absl_crc_internal",
        "absl_debugging_internal",
        "absl_demangle_internal",
        "absl_die_if_null",
        "absl_examine_stack",
        "absl_exponential_biased",
        "absl_failure_signal_handler",
        "absl_flags_commandlineflag",
        "absl_flags_commandlineflag_internal",
        "absl_flags_config",
        "absl_flags_internal",
        "absl_flags_marshalling",
        "absl_flags_parse",
        "absl_flags_private_handle_accessor",
        "absl_flags_program_name",
        "absl_flags_reflection",
        "absl_flags_usage",
        "absl_flags_usage_internal",
        "absl_graphcycles_internal",
        "absl_hash",
        "absl_hashtablez_sampler",
        "absl_int128",
        "absl_kernel_timeout_internal",
        "absl_leak_check",
        "absl_log_entry",
        "absl_log_flags",
        "absl_log_globals",
        "absl_log_initialize",
        "absl_log_internal_check_op",
        "absl_log_internal_conditions",
        "absl_log_internal_fnmatch",
        "absl_log_internal_format",
        "absl_log_internal_globals",
        "absl_log_internal_log_sink_set",
        "absl_log_internal_message",
        "absl_log_internal_nullguard",
        "absl_log_internal_proto",
        "absl_log_severity",
        "absl_log_internal_structured_proto",
        "absl_log_sink",
        "absl_low_level_hash",
        "absl_malloc_internal",
        "absl_periodic_sampler",
        "absl_random_distributions",
        "absl_random_internal_distribution_test_util",
        "absl_random_internal_platform",
        "absl_random_internal_pool_urbg",
        "absl_random_internal_randen",
        "absl_random_internal_randen_hwaes",
        "absl_random_internal_randen_hwaes_impl",
        "absl_random_internal_randen_slow",
        "absl_random_internal_seed_material",
        "absl_random_seed_gen_exception",
        "absl_random_seed_sequences",
        "absl_raw_hash_set",
        "absl_raw_logging_internal",
        "absl_scoped_set_env",
        "absl_spinlock_wait",
        "absl_stacktrace",
        "absl_status",
        "absl_statusor",
        "absl_strerror",
        "absl_strings",
        "absl_strings_internal",
        "absl_string_view",
        "absl_str_format_internal",
        "absl_symbolize",
        "absl_synchronization",
        "absl_throw_delegate",
        "absl_time",
        "absl_time_zone",
        "absl_vlog_config_internal",
        "zlib",
        "zlibstatic-ng",
        "libmodpbase64"
    ])
elif (os.name == cesium_build_utils.OS_LINUX):
    libraries.extend([
        "crypto",
        "libz-ng",
        "liblibmodpbase64"
    ])
    env.Append(LIBPATH=["/usr/lib/x86_64-linux-gnu"])
    env.Append(CPPPATH=["/usr/include/x86_64-linux-gnu"])

env.Append(
    LIBS=libraries,
    LIBPATH=[
        f"{root_dir_native}/CesiumGltfReader/{current_build_config}",
        f"{root_dir_native}/CesiumAsync/{current_build_config}",
        f"{root_dir_native}/CesiumJsonReader/{current_build_config}",
        f"{root_dir_native}/CesiumGltf/{current_build_config}",
        f"{root_dir_native}/CesiumUtility/{current_build_config}",
        f"{root_dir_native}/CesiumGeospatial/{current_build_config}",
        f"{root_dir_native}/Cesium3DTilesSelection/{current_build_config}",
        f"{root_dir_native}/CesiumRasterOverlays/{current_build_config}",
        f"{root_dir_native}/CesiumGeometry/{current_build_config}",
        f"{root_dir_native}/Cesium3DTilesReader/{current_build_config}",
        f"{root_dir_native}/CesiumGltfContent/{current_build_config}",
        f"{root_dir_native}/CesiumQuantizedMeshTerrain/{current_build_config}",
        f"{root_dir_native}/Cesium3DTilesContent/{current_build_config}",
        cesium_build_utils.get_root_dir_native() + "/libs/gsl",
        cesium_build_utils.get_root_dir_native() + "/libs/absl",
        cesium_build_utils.get_root_dir_native() + "/libs",
        cesium_build_utils.get_root_dir() + "/third_party/litehtml",
        cesium_build_utils.find_ezvcpkg_path(
        ) + "/installed/%s/lib" % (cesium_build_utils.determine_triplet())
    ]
)

# This was a nightmare, so I abstracted it into a function, the function itself is also a nightmare
if (os.name == cesium_build_utils.OS_LINUX):
    cesium_build_utils.link_abseil_libs(env)
