#!/usr/bin/env python3
"""Intel oneAPI Fortran discovery helpers for no-Abaqus validation."""

from __future__ import annotations

import os
import shutil
import subprocess
from pathlib import Path
from typing import Iterable


COMPILER_CANDIDATES = ("ifx", "ifort")
ONEAPI_VARS_CANDIDATES = [
    Path(r"C:\Program Files (x86)\Intel\oneAPI\compiler\latest\env\vars.bat"),
    Path(r"C:\Program Files\Intel\oneAPI\compiler\latest\env\vars.bat"),
    Path(r"C:\Program Files (x86)\Intel\oneAPI\setvars.bat"),
    Path(r"C:\Program Files\Intel\oneAPI\setvars.bat"),
]


class FortranToolchain:
    def __init__(self, *, name: str, executable: str, env_script: Path | None):
        self.name = name
        self.executable = executable
        self.env_script = env_script


def compiler_candidates(preference: str | None = None) -> list[str]:
    preference = (preference or os.environ.get("HARNESS_FORTRAN_COMPILER") or "auto").lower()
    if preference == "auto":
        return list(COMPILER_CANDIDATES)
    if preference not in COMPILER_CANDIDATES:
        raise ValueError(f"Unsupported HARNESS_FORTRAN_COMPILER: {preference}")
    return [preference]


def discover_oneapi_env_script(env: dict[str, str] | None = None) -> Path | None:
    env = env or os.environ
    configured = env.get("HARNESS_ONEAPI_VARS_BAT")
    if configured:
        path = Path(configured)
        return path if path.exists() else None

    for path in ONEAPI_VARS_CANDIDATES:
        if path.exists():
            return path
    return None


def resolve_toolchain(env: dict[str, str] | None = None) -> FortranToolchain | None:
    env = env or os.environ
    candidates = compiler_candidates(env.get("HARNESS_FORTRAN_COMPILER"))
    for compiler in candidates:
        resolved = shutil.which(compiler)
        if resolved:
            return FortranToolchain(name=compiler, executable=resolved, env_script=None)

    env_script = discover_oneapi_env_script(env)
    if env_script is None:
        return None

    compiler = candidates[0]
    return FortranToolchain(name=compiler, executable=compiler, env_script=env_script)


def shell_join(args: Iterable[str | Path]) -> str:
    return subprocess.list2cmdline([str(arg) for arg in args])


def quote_path(path: str | Path) -> str:
    return shell_join([path])


def cmd_executable(env: dict[str, str] | None = None) -> str:
    env = env or os.environ
    return env.get("ComSpec") or shutil.which("cmd.exe") or shutil.which("cmd") or "cmd"


def cmd_minimal_path(env: dict[str, str] | None = None) -> str:
    env = env or os.environ
    system_root = env.get("SystemRoot") or r"C:\Windows"
    return f"{system_root}\\System32;{system_root}"


def wrap_command(toolchain: FortranToolchain, args: list[str | Path]) -> str:
    command = shell_join(args)
    if toolchain.env_script is None:
        return command

    env_script = quote_path(toolchain.env_script)
    cmd = quote_path(cmd_executable())
    path = cmd_minimal_path()
    return f'{cmd} /d /s /c "set "PATH={path}" && call {env_script} intel64 >nul && {command}"'
