"""Setup script with optional mypyc compilation."""
import os
import subprocess
from pathlib import Path
from setuptools import setup, find_packages
from typing import List
import sys


# =============================================================================
# CONFIGURATION
# =============================================================================

# Environment variables control build behavior.
# Falls back to build-config.json if env var is not set.
def _resolve_enable_mypyc() -> bool:
    env_val = os.environ.get("ENABLE_MYPYC")
    if env_val is not None:
        return env_val.lower() in ("true", "1", "yes")
    # Fallback: read from build-config.json
    config_path = Path(__file__).parent / "build-config.json"
    if config_path.exists():
        import json
        try:
            with open(config_path) as f:
                config = json.load(f)
            return bool(config.get("build", {}).get("enable_mypyc", False))
        except Exception:
            pass
    return False

ENABLE_MYPYC = _resolve_enable_mypyc()

# Source directory
SRC_DIR = "src"
PACKAGE_NAME = "matrice"
SOURCE_DIR = f"{SRC_DIR}/{PACKAGE_NAME}"


def get_version() -> str:
    """Get version from environment or default."""
    return os.environ.get("PACKAGE_VERSION", "0.0.0.dev0")


VERSION = get_version()


def get_package_data():
    """Get package data for mypyc compiled files and type hints."""
    return {
        PACKAGE_NAME: [
            "py.typed",
            "*.pyi",
            "**/*.pyi",
        ],
    }


def run_stub_generator_script():
    """Run the repo's stub generator script before mypycify."""
    script_path = Path(__file__).parent / "stub_generation.py"
    if not script_path.exists():
        print(f"Warning: Stub generator script not found: {script_path}")
        return

    cmd = [sys.executable, str(script_path)]
    print("Running stub generator:", " ".join(cmd))
    subprocess.run(cmd, check=True)


def ensure_py_typed():
    """Create py.typed file if it doesn't exist."""
    src_py_typed = os.path.join(SOURCE_DIR, "py.typed")
    if not os.path.exists(src_py_typed):
        with open(src_py_typed, "w") as f:
            f.write("")
        print("Created py.typed file")


def discover_source_files() -> List[str]:
    """Discover all Python source files under the package's SOURCE_DIR.

    Excludes common non-source directories. Returns relative paths from repo root
    suitable for mypycify.
    """
    src_root = Path(SOURCE_DIR)
    results: List[str] = []
    if not src_root.exists():
        return results

    exclude_dirs = {"__pycache__", "tests", "test", "docs"}
    for path in src_root.rglob("*.py"):
        # Skip excluded directories
        if any(part in exclude_dirs for part in path.parts):
            continue
        # Keep everything in the matrice package tree
        results.append(str(path).replace("\\", "/"))

    print(f"Discovered {len(results)} Python files for compilation")
    return results


def get_ext_modules():
    """Get extension modules for mypyc compilation."""
    if not ENABLE_MYPYC:
        print("=" * 60)
        print("Building PURE PYTHON package (mypyc disabled)")
        print("=" * 60)
        return []

    try:
        from mypyc.build import mypycify
    except ImportError:
        print("WARNING: mypyc not available, building pure Python package")
        return []

    print("=" * 60)
    print("Building MYPYC COMPILED package")
    print("=" * 60)

    modules = discover_source_files()
    print(f"Compiling {len(modules)} modules with mypyc")

    mypyc_options = [
        "--follow-imports=skip",
        "--ignore-missing-imports",
    ]

    return mypycify(mypyc_options + modules, opt_level="3")


# =============================================================================
# SETUP
# =============================================================================

# Ensure py.typed exists for type hints
ensure_py_typed()

# Run stub generator
run_stub_generator_script()

setup(
    name=PACKAGE_NAME,
    version=VERSION,
    package_dir={"": SRC_DIR},
    packages=find_packages(where=SRC_DIR),
    include_package_data=True,
    package_data=get_package_data(),
    ext_modules=get_ext_modules(),
    zip_safe=False,
    python_requires=">=3.8",
)
