import os
import sys

# Ensure site_tools and metac tool are loaded
env = Environment(tools=["default", "metac"], toolpath=["site_scons/site_tools"])

# The commands SCons spawns resolve the external tools they reference (doxygen,
# for example) against env["ENV"] - which on Windows is derived from the registry
# rather than the invoking shell - so the caller's PATH is merged in, appended
# after the entries the toolchain has installed and de-duplicated
_toolchain_path = env["ENV"].get("PATH", "").split(os.pathsep)
_toolchain_path += [p for p in os.environ.get("PATH", "").split(os.pathsep) if p and p not in _toolchain_path]
env["ENV"]["PATH"] = os.pathsep.join(_toolchain_path)

vars = Variables()
vars.Add(EnumVariable("METAC", "MetaC code generation mode: on (unconditional), auto (incremental), off (disabled)", "@metac_mode@", allowed_values=("auto", "on", "off"), ignorecase=2))
vars.Add(EnumVariable("BUILD_TYPE", "Build configuration type", "debug", allowed_values=("debug", "release"), ignorecase=2))
vars.Update(env)
Help(vars.GenerateHelpText(env))

# Load site-local configuration if present
_site = ".metac/scons.site"
if os.path.exists(_site):
  _site_vars = {}
  with open(_site, "r") as _f:
    exec(_f.read(), _site_vars)
  for _k, _v in _site_vars.items():
    if _k == "PYTHON":
      env["PYTHON"] = _v
    elif _k == "METAC_PYTHONPATH":
      env["METAC_PYTHONPATH"] = _v

# Compiler configuration based on build type
if env["BUILD_TYPE"].lower() == "debug":
  if env.get("PLATFORM") == "win32" and env.get("CC") in ("cl", "msvc"):
    env.Append(CCFLAGS=["/Od", "/Zi", "/MDd"])
  else:
    env.Append(CCFLAGS=["-g", "-O0"])
else:
  if env.get("PLATFORM") == "win32" and env.get("CC") in ("cl", "msvc"):
    env.Append(CCFLAGS=["/O2", "/DNDEBUG", "/MD"])
  else:
    env.Append(CCFLAGS=["-O3", "-DNDEBUG"])

project = "@project@"
module = "@module@"

metac_mod = env.MetaCModule(
  module,
  directory=".",
  main_dependency=f"{module}.py",
)

# The forced generation mode runs the generator unconditionally so the python
# side transient changes never slip through unadvertised; the C-level build
# avoidance stays content-driven - recompilation happens only when the emitted
# code actually differs, matching the cmake and meson backends

app_sources = [f"{project}.c"] if os.path.exists(f"{project}.c") else []
all_sources = app_sources + metac_mod.sources

if all_sources:
  app = env.Program(target=project, source=all_sources)
  Default(app)

if os.path.exists("Doxyfile"):
  doc = env.Command("reference", [metac_mod.header, "Doxyfile"], "doxygen Doxyfile")
  Default(doc)
