python := if os() == "windows" { ".venv\\Scripts\\python.exe" } else { ".venv/bin/python" }
_venv_actionlint := if os() == "windows" { ".venv\\Scripts\\actionlint.exe" } else { ".venv/bin/actionlint" }
actionlint := if path_exists(_venv_actionlint) == "true" { _venv_actionlint } else { "actionlint" }
diff_cover := if os() == "windows" { ".venv\\Scripts\\diff-cover.exe" } else { ".venv/bin/diff-cover" }

set windows-shell := ["cmd.exe", "/c"]

# Create venv and install package with test deps
install:
    @just --justfile {{justfile()}} _install-{{os()}}

[private]
_install-windows:
    @python -c "import sys; sys.exit(0 if sys.version_info >= (3, 11) else 1)" || (echo error: Python 3.11+ required >&2 && exit 1)
    python -m venv .venv
    @if where actionlint >nul 2>&1 ({{python}} -m pip install -e ".[test,dev]") else ({{python}} -m pip install -e ".[test,dev,actionlint]")

[private]
_install-linux: _install-posix
[private]
_install-macos: _install-posix

[private]
_install-posix:
    @python3 -c "import sys; sys.exit(0 if sys.version_info >= (3, 11) else 1)" || (echo "error: Python 3.11+ required" >&2 && exit 1)
    python3 -m venv .venv
    @if command -v actionlint > /dev/null 2>&1 || [ "${CLAUDE_CODE_REMOTE:-}" = "true" ]; then \
        {{python}} -m pip install -e ".[test,dev]"; \
    else \
        {{python}} -m pip install -e ".[test,dev,actionlint]"; \
    fi

[private]
_require-venv:
    @just --justfile {{justfile()}} _require-venv-{{ if os() == "windows" { "windows" } else { "posix" } }}

[private]
_require-venv-windows:
    @if not exist {{python}} (echo error: venv not found — run 'just install' first >&2 && exit 1)

[private]
_require-venv-posix:
    @[ -x {{python}} ] || (echo "error: venv not found — run 'just install' first" >&2 && exit 1)

# Format code with black
fmt: _require-venv
    {{python}} -m black src tests

# Check formatting with black (non-destructive)
check: _require-venv
    {{python}} -m black --check src tests

# Run tests
test: _require-venv
    {{python}} -m pytest

# Run the CI test matrix locally in Docker
test-matrix: _require-venv
    {{python}} .github/scripts/run_local_matrix.py

# Run ruff and mypy static analysis
lint: _require-venv
    {{python}} -m ruff check src tests .github/scripts/ scripts/
    {{python}} -m mypy src tests .github/scripts/ scripts/ --ignore-missing-imports

# Check that every okf_core name referenced in README.md is actually exported
check-readme-exports: _require-venv
    {{python}} .github/scripts/check_readme_exports.py

# Lint GitHub Actions workflows with actionlint (skipped in Claude cloud instances)
lint-actions: _require-venv
    @just --justfile {{justfile()}} _lint-actions-{{os()}}

[private]
_lint-actions-linux: _lint-actions-posix
[private]
_lint-actions-macos: _lint-actions-posix

[private]
_lint-actions-posix:
    @if [ "${CLAUDE_CODE_REMOTE:-}" = "true" ] && ! command -v {{actionlint}} > /dev/null 2>&1; then \
        echo "actionlint not available in cloud instance; skipping workflow lint"; \
    else \
        {{actionlint}} .github/workflows/publish.yml .github/workflows/test.yml; \
    fi

[private]
_lint-actions-windows:
    @if "%CLAUDE_CODE_REMOTE%" == "true" (where actionlint >nul 2>&1 || (echo actionlint not available in cloud instance; skipping workflow lint && exit /b 0)) else ({{actionlint}} .github/workflows/publish.yml .github/workflows/test.yml)

# Run pytest with branch coverage and gate PR-changed/new lines against origin/main
# (skipped when there's no comparable base to diff against, e.g. running locally on main itself)
coverage-diff: _require-venv
    @just --justfile {{justfile()}} _coverage-diff-{{ if os() == "windows" { "windows" } else { "posix" } }}

[private]
_coverage-diff-posix:
    @if ! git rev-parse --verify -q origin/main > /dev/null 2>&1 || [ "$(git rev-parse HEAD)" = "$(git rev-parse origin/main)" ]; then \
        echo "no comparable base (origin/main unavailable or HEAD matches origin/main); skipping coverage-diff"; \
    else \
        {{python}} -m pytest --cov=okf_core --cov-branch --cov-report=xml && \
        {{diff_cover}} coverage.xml --compare-branch=origin/main --fail-under=90; \
    fi

[private]
_coverage-diff-windows:
    @git rev-parse --verify -q origin/main >nul 2>&1 & \
        if errorlevel 1 (echo no comparable base ^(origin/main unavailable or HEAD matches origin/main^); skipping coverage-diff) else (git diff --quiet origin/main -- >nul 2>&1 && (echo no comparable base ^(origin/main unavailable or HEAD matches origin/main^); skipping coverage-diff) || ({{python}} -m pytest --cov=okf_core --cov-branch --cov-report=xml && {{diff_cover}} coverage.xml --compare-branch=origin/main --fail-under=90))

# Run check + lint + test (local superset of CI; also lints scripts/)
ci: check lint lint-actions check-readme-exports test coverage-diff

# Run search benchmarks
benchmark-search: _require-venv
    {{python}} scripts/benchmark_search.py
