from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]


def test_formal_compose_accepts_portainer_environment_without_env_file() -> None:
    compose = ROOT.joinpath("compose.yaml").read_text(encoding="utf-8")

    assert "env_file:" not in compose
    assert "APP_ENCRYPTION_KEY: ${APP_ENCRYPTION_KEY:?" in compose
    assert "${APP_STORAGE_PATH:-./data}:/app/data" in compose
    assert '"${APP_PUBLISH_PORT:-8876}:8765"' in compose
    assert "read_only: true" in compose
    assert "no-new-privileges:true" in compose
    assert "cap_drop:\n      - ALL" in compose


def test_preflight_migrates_before_web_and_cannot_default_to_formal_storage() -> None:
    compose = ROOT.joinpath("compose.preflight.yaml").read_text(encoding="utf-8")

    storage_guard = "${APP_STORAGE_PATH:?APP_STORAGE_PATH must be a dedicated preflight directory}"
    assert storage_guard in compose
    assert "/app/data/legacy-review.db" in compose
    assert "/app/data/xiaobai.db" in compose
    assert "/app/data/migration-report.json" in compose
    assert "condition: service_completed_successfully" in compose
    assert '"${APP_PUBLISH_PORT:-8876}:8765"' in compose
    assert "8765:8765" not in compose


def test_portainer_preflight_is_pinned_to_the_release_candidate() -> None:
    guide = ROOT.joinpath("docs", "portainer-preflight.md").read_text(encoding="utf-8")
    manifest = ROOT.joinpath("docs", "final", "release-candidate.md").read_text(
        encoding="utf-8"
    )

    git_tag = "xiaobai-next-rc-20260730-1"
    image_tag = "xiaobai-review-next:rc-20260730-1"
    assert f"refs/tags/{git_tag}" in guide
    assert f"refs/tags/{git_tag}" in manifest
    assert image_tag in guide
    assert image_tag in manifest
    assert "| Repository reference | `refs/heads/main` |" not in guide
    assert "546c5af1a3010bbf0cf37e5d8b1a440fe6dfbfe80b471cddf430d4363a7b1a4a" in manifest
    for expected in ("用户 | 3", "自选 | 6", "选股归档 | 107", "策略跟踪 | 16"):
        assert expected in manifest


def test_image_context_excludes_private_and_non_runtime_assets() -> None:
    ignored = {
        line.strip()
        for line in ROOT.joinpath(".dockerignore").read_text(encoding="utf-8").splitlines()
        if line.strip() and not line.lstrip().startswith("#")
    }
    assert {".git", ".venv", "data", ".env", "docs/evidence", "tests"} <= ignored

    dockerfile = ROOT.joinpath("Dockerfile").read_text(encoding="utf-8")
    assert "COPY . " not in dockerfile
    assert "COPY backend/ ./backend/" in dockerfile
    assert "COPY config/ ./config/" in dockerfile
    assert "COPY tools/ ./tools/" in dockerfile
    assert "COPY --from=frontend-build /build/frontend/dist ./frontend/dist" in dockerfile
