import os
import platform
import shutil
import subprocess

import lit.formats

config.name = 'ispc'
config.suffixes = ['.ispc', '.ll', '.cpp']

# testFormat: The test format to use to interpret tests.
config.test_format = lit.formats.ShTest(False)

# test_source_root: The root path where tests are located.
config.test_source_root = os.path.dirname(__file__)
# ispc root folder
config.ispc_build_dir = lit_config.params.get('ispc_build_dir')
# test_exec_root: The root path where tests should be run.
ispc_test_exec_root = lit_config.params.get('ispc_test_exec_root','')
# LLVM version used to build ISPC
ispc_llvm_version_number = lit_config.params.get('ispc_llvm_version_number','')

if ispc_test_exec_root != '':
    config.test_exec_root = ispc_test_exec_root

config.substitutions.append(('%{ispc}', 'ispc'))
config.substitutions.append(('%{ispc-opt}', 'ispc-opt'))
config.substitutions.append(('FileCheck', 'FileCheck'))
config.substitutions.append(('%{cc}', 'clang'))
config.substitutions.append(('%{cxx}', 'clang++'))
config.substitutions.append(('%{ispc_include}', os.path.join(config.ispc_build_dir, 'include')))
config.substitutions.append(('%{ispc_lib}', os.path.join(config.ispc_build_dir, 'lib')))

print("Config:")

# LLVM version
llvm_version_major = int(ispc_llvm_version_number.split('.')[0])

if llvm_version_major >= 18:
    print("LLVM_18_0+: YES")
    config.available_features.add("LLVM_18_0+")
else:
    print("LLVM_18_0+: NO")

if llvm_version_major >= 19:
    print("LLVM_19_0+: YES")
    config.available_features.add("LLVM_19_0+")
else:
    print("LLVM_19_0+: NO")

if llvm_version_major >= 20:
    print("LLVM_20_0+: YES")
    config.available_features.add("LLVM_20_0+")
else:
    print("LLVM_20_0+: NO")

if llvm_version_major >= 21:
    print("LLVM_21_0+: YES")
    config.available_features.add("LLVM_21_0+")
else:
    print("LLVM_21_0+: NO")

if llvm_version_major >= 22:
    print("LLVM_22_0+: YES")
    config.available_features.add("LLVM_22_0+")
else:
    print("LLVM_22_0+: NO")

# Windows target OS is enabled
windows_enabled = lit_config.params.get('windows_enabled')
if windows_enabled == "ON":
    print("WINDOWS_ENABLED: YES")
    config.available_features.add("WINDOWS_ENABLED")
elif windows_enabled == "OFF":
    print("WINDOWS_ENABLED: NO")
else:
    sys.exit("Cannot parse windows_enabled: " + windows_enabled)

# Linux target OS is enabled
linux_enabled = lit_config.params.get('linux_enabled')
if linux_enabled == "ON":
    print("LINUX_ENABLED: YES")
    config.available_features.add("LINUX_ENABLED")
elif linux_enabled == "OFF":
    print("LINUX_ENABLED: NO")
else:
    sys.exit("Cannot parse linux_enabled: " + linux_enabled)

# PS target OSes are enabled
ps_enabled = lit_config.params.get('ps_enabled')
if ps_enabled == "ON":
    print("PS_ENABLED: YES")
    config.available_features.add("PS_ENABLED")
elif ps_enabled == "OFF":
    print("PS_ENABLED: NO")
else:
    sys.exit("Cannot parse ps_enabled: " + ps_enabled)

# ARM support on macOS target is enabled
macos_arm_enabled = lit_config.params.get('macos_arm_enabled')
if macos_arm_enabled == "ON":
    print("MACOS_ARM_ENABLED: YES")
    config.available_features.add("MACOS_ARM_ENABLED")
elif macos_arm_enabled == "OFF":
    print("MACOS_ARM_ENABLED: NO")
else:
    sys.exit("Cannot parse macos_arm_enabled: " + macos_arm_enabled)

# x86 backend
x86_enabled = lit_config.params.get('x86_enabled')
if x86_enabled == "ON":
    print("X86_ENABLED: YES")
    config.available_features.add("X86_ENABLED")
elif x86_enabled == "OFF":
    print("X86_ENABLED: NO")
else:
    sys.exit("Cannot parse x86_enabled: " + x86_enabled)

# ARM backend
arm_enabled = lit_config.params.get('arm_enabled')
if arm_enabled == "ON":
    print("ARM_ENABLED: YES")
    config.available_features.add("ARM_ENABLED")
elif arm_enabled == "OFF":
    print("ARM_ENABLED: NO")
else:
    sys.exit("Cannot parse arm_enabled: " + arm_enabled)

# RISC-V backend
riscv_enabled = lit_config.params.get('riscv_enabled')
if riscv_enabled == "ON":
    print("RISCV_ENABLED: YES")
    config.available_features.add("RISCV_ENABLED")
elif riscv_enabled == "OFF":
    print("RISCV_ENABLED: NO")
else:
    sys.exit("Cannot parse riscv_enabled: " + riscv_enabled)

# WebAssembly backend
wasm_enabled = lit_config.params.get('wasm_enabled')
if wasm_enabled == "ON":
    print("WASM_ENABLED: YES")
    config.available_features.add("WASM_ENABLED")
elif wasm_enabled == "OFF":
    print("WASM_ENABLED: NO")
else:
    sys.exit("Cannot parse wasm_enabled: " + wasm_enabled)

# iOS target
macos_ios_enabled = lit_config.params.get('macos_ios_enabled')
if macos_ios_enabled == "ON":
    print("MACOS_IOS_ENABLED: YES")
    config.available_features.add("MACOS_IOS_ENABLED")
elif macos_ios_enabled == "OFF":
    print("MACOS_IOS_ENABLED: NO")
else:
    sys.exit("Cannot parse macos_ios_enabled: " + macos_ios_enabled)

# Xe backend
xe_enabled = lit_config.params.get('xe_enabled', '0')
if xe_enabled == "ON":
    print("XE_ENABLED: YES")
    config.available_features.add("XE_ENABLED")
elif xe_enabled == "OFF":
    print("XE_ENABLED: NO")
else:
    sys.exit("Cannot parse xe_enabled: " + xe_enabled)

# ISPC library
ispc_lib_enabled = lit_config.params.get('ispc_lib_enabled', '0')
if ispc_lib_enabled == "ON":
    print("ISPC_LIBRARY: YES")
    config.available_features.add("ISPC_LIBRARY")
elif ispc_lib_enabled == "OFF":
    print("ISPC_LIBRARY: NO")
else:
    sys.exit("Cannot parse ispc_lib_enabled: " + ispc_lib_enabled)

# ISPC library with JIT
ispc_lib_jit_enabled = lit_config.params.get('ispc_lib_jit_enabled', '0')
if ispc_lib_jit_enabled == "ON":
    print("ISPC_LIBRARY_JIT: YES")
    config.available_features.add("ISPC_LIBRARY_JIT")
elif ispc_lib_jit_enabled == "OFF":
    print("ISPC_LIBRARY_JIT: NO")
else:
    sys.exit("Cannot parse ispc_lib_jit_enabled: " + ispc_lib_jit_enabled)

# Ocloc
ocloc_available = shutil.which("ocloc") is not None
if ocloc_available:
    print("OCLOC_INSTALLED: YES")
    config.available_features.add("OCLOC_INSTALLED")
else:
    print("OCLOC_INSTALLED: NO")

# SDE
sde_available = shutil.which("sde") is not None
if sde_available:
    print("SDE_INSTALLED: YES")
    config.available_features.add("SDE_INSTALLED")
else:
    print("SDE_INSTALLED: NO")

# detect host OS
if platform.system() == "Windows":
    print("HOST OS: WINDOWS")
    config.available_features.add("WINDOWS_HOST")
elif platform.system() == "Linux":
    print("HOST OS: LINUX")
    config.available_features.add("LINUX_HOST")
elif platform.system() == "Darwin":
    print("HOST OS: MACOS")
    config.available_features.add("MACOS_HOST")
else:
    print("HOST OS: UNKNOWN")

# detect host arch
host_arch = platform.machine()
if host_arch == "x86_64":
    print("HOST ARCH: X86_64")
    config.available_features.add("X86_64_HOST")
elif host_arch == "aarch64":
    print("HOST ARCH: AARCH64")
    config.available_features.add("AARCH64_HOST")
elif host_arch == "riscv64":
    print("HOST ARCH: RISCV64")
    config.available_features.add("RISCV64_HOST")
else:
    print(f"HOST ARCH: {host_arch} (unknown)")
    config.available_features.add("UNKNOWN_HOST_ARCH")

# Detect that lit-tests run under ASAN.
# This checks kind of requires us to run ASAN tests always with some ASAN_OPTIONS
asan_mode = os.environ.get("ASAN_OPTIONS", False)
if asan_mode:
    config.available_features.add("ASAN_RUN")
    print("ASAN_RUN: YES")
else:
    print("ASAN_RUN: NO")

