"""진입 스크립트가 자기와 같은 배치의 모듈 트리를 import 하게 만든다.

okstra 의 파이썬 진입 스크립트는 두 배치 중 하나에 놓인다.

* 레포 체크아웃 — `scripts/okstra-*.py` 옆에 `scripts/okstra_ctl/` 이 있다.
* 설치본 — `~/.okstra/bin/okstra-*.py` 의 짝은 `~/.okstra/lib/python/` 이다.

짝을 `sys.path` **맨 앞**에 두어야 하는 이유는 상속된 `PYTHONPATH` 다.
`okstra <cmd>` 는 자식 프로세스에 npm 패키지의 `runtime/python` 을 먼저 담은
`PYTHONPATH` 를 물려준다(`src/lib/paths.mts` 의 `buildPythonpath`). 짝을 뒤에
붙이면 설치본 스크립트가 npm 패키지 쪽 모듈을 import 하게 되고, 설치본과 npm
패키지의 버전이 어긋나 있으면 그 스크립트는 import 에서 죽는다. 실행되는
스크립트와 그 스크립트가 읽는 모듈은 항상 같은 버전이어야 한다.
"""
from __future__ import annotations

import os
import sys
from pathlib import Path


def _home_lib() -> Path:
    home = Path(os.environ.get("OKSTRA_HOME", str(Path.home() / ".okstra")))
    return home / "lib" / "python"


def _prepend(path: Path) -> None:
    text = str(path)
    if text in sys.path:
        sys.path.remove(text)
    sys.path.insert(0, text)


def _append(path: Path) -> None:
    text = str(path)
    if path.is_dir() and text not in sys.path:
        sys.path.append(text)


def prefer_colocated_modules(entry_file: str, probe: str) -> None:
    """`entry_file` 의 짝이 되는 모듈 트리를 `sys.path` 맨 앞에 둔다.

    `probe` 는 그 트리 안에 있어야 하는 파일의 상대 경로다
    (예: `okstra_ctl/report_views.py`). 디렉터리 존재만 보면 그 스크립트가
    필요로 하는 새 모듈이 아직 없는 낡은 설치본도 후보로 뽑히므로, 실제로
    쓰는 파일이 있는 쪽을 고른다. 어느 쪽에도 없으면 설치본을 앞에 둔다 —
    빠진 모듈은 상속된 경로에서 채워질 수 있고, 채워지지 않으면 ImportError
    로 드러난다.
    """
    entry_dir = Path(entry_file).resolve().parent
    home_lib = _home_lib()
    if (entry_dir / probe).is_file():
        primary, fallback = entry_dir, home_lib
    else:
        primary, fallback = home_lib, entry_dir
    if primary.is_dir():
        _prepend(primary)
    _append(fallback)
