#!/usr/bin/env python3
"""最短路径自检：两个入口共用一次六轨计算，不保留第二模型。"""
import ast
import sys
from pathlib import Path

if len(sys.argv) > 1:
    if sys.argv[1] in ("-h", "--help"):
        print(__doc__.strip())
        sys.exit(0)
    if sys.argv[1] in ("-v", "--version"):
        print("fenxuan shortest path 1.6.0")
        sys.exit(0)
    print(f"unknown arguments: {sys.argv[1:]}", file=sys.stderr)
    sys.exit(2)

SOURCE = Path(__file__).parents[1] / "server" / "app.py"
text = SOURCE.read_text(encoding="utf-8")
tree = ast.parse(text)
separate_text = SOURCE.with_name("separate.py").read_text(encoding="utf-8")


def call_names(nodes):
    names = []
    for node in nodes:
        for child in ast.walk(node):
            if not isinstance(child, ast.Call):
                continue
            func = child.func
            if isinstance(func, ast.Attribute) and isinstance(func.value, ast.Name):
                names.append(f"{func.value.id}.{func.attr}")
    return names


profiles = next(node for node in tree.body
                if isinstance(node, ast.Assign)
                and any(isinstance(target, ast.Name) and target.id == "PROFILES"
                        for target in node.targets))
assert set(ast.literal_eval(profiles.value)) == {"vocal", "stems6"}

pipeline = next(node for node in tree.body
                if isinstance(node, ast.FunctionDef) and node.name == "run_pipeline")
pipeline_calls = call_names(pipeline.body)
assert pipeline_calls.count("sep.separate") == 1
assert "sep.separate_roformer" not in pipeline_calls
assert "_mix_stems" in text
assert "cache_id = content_id" in text
assert "while chunk := await file.read(1024 * 1024)" in text
assert 'device = "cuda"' in separate_text and "torch.cuda.is_available()" in separate_text
assert "ZipFile" not in call_names(pipeline.body)
for removed in ('"stems4"', '"/api/refine"', '"/api/tracks-zip/{job_id}"'):
    assert removed not in text

print("SHORT_PATH: PASS (two entrances, one six-stem calculation)")
