# packages/sdk-python — Python SDK tasks.
#
# The underlying tooling is `uv` + `maturin`. Callers should go through these
# recipes so the commands are discoverable and consistent.

import "../../justfiles/common.just"

# `source_directory()` (not `justfile_directory()`) because this file is
# imported as a `mod` from `packages/sdk.justfile` via `justfile` (root).
# `justfile_directory()` always resolves to the *root* justfile's directory
# regardless of module depth, which would point `_pkg` / `_spec` / `_generated`
# at the repo root instead of `packages/sdk-python/`.
_pkg := source_directory()
_spec := source_directory() / ".." / "api-spec" / "openapi.json"
_generated := source_directory() / "python" / "openapp_sdk" / "models" / "_generated.py"

_:
    @just --list

# Install/refresh the dev virtualenv at `.venv` using `uv`.
_venv:
    cd {{ _pkg }} && uv sync --all-extras

# Fast iteration: `maturin develop` builds the bridge in-place (debug mode).
build-develop: _venv
    cd {{ _pkg }} && uv run maturin develop --features pyo3/extension-module

# Release wheel for the local platform (CI uses `maturin-action` to cross-build).
wheel: _venv
    cd {{ _pkg }} && uv run maturin build --release --strip

# sdist for PyPI (includes the Rust source so manual builds are possible).
sdist: _venv
    cd {{ _pkg }} && uv run maturin sdist

# Run the full test suite (unit + integration; integration tests auto-skip without
# `OPENAPP_SDK_TEST_API_KEY`).
test: _venv
    cd {{ _pkg }} && uv run pytest -v

# Run just the unit suite — fast, no backend needed.
test-unit: _venv
    cd {{ _pkg }} && uv run pytest -v tests/unit

# Ruff + mypy.
lint: _venv
    cd {{ _pkg }} && uv run ruff check .
    cd {{ _pkg }} && uv run ruff format --check .
    cd {{ _pkg }} && uv run mypy

lint-fix: _venv
    cd {{ _pkg }} && uv run ruff format .
    cd {{ _pkg }} && uv run ruff check --fix .

# Regenerate the committed Pydantic models from the OpenAPI spec.
openapi-gen: _venv
    #!/usr/bin/env bash
    set -euo pipefail
    cd "{{ _pkg }}"
    tmp="$(mktemp)"
    trap 'rm -f "$tmp"' EXIT
    uv run datamodel-codegen \
        --input "{{ _spec }}" \
        --input-file-type openapi \
        --output "$tmp" \
        --output-model-type pydantic_v2.BaseModel \
        --target-python-version 3.10 \
        --use-standard-collections \
        --use-union-operator \
        --use-annotated \
        --disable-timestamp \
        --collapse-root-models \
        --field-constraints \
        --enum-field-as-literal one \
        --use-schema-description \
        --formatters ruff-format ruff-check
    # Drop the generator's own `# generated by datamodel-codegen: ... filename: ...`
    # banner (first line) because it embeds the host-specific absolute path of
    # the spec file and makes the check non-reproducible across machines.
    {
        printf '# @generated by `just sdk::python::openapi-gen` — DO NOT EDIT.\n'
        printf '# Source: packages/api-spec/openapi.json\n\n'
        tail -n +2 "$tmp"
    } > "{{ _generated }}"

# Drift check for the committed Pydantic models.
openapi-check: _venv
    #!/usr/bin/env bash
    set -euo pipefail
    cd "{{ _pkg }}"
    tmp="$(mktemp)"
    trap 'rm -f "$tmp"' EXIT
    uv run datamodel-codegen \
        --input "{{ _spec }}" \
        --input-file-type openapi \
        --output "$tmp" \
        --output-model-type pydantic_v2.BaseModel \
        --target-python-version 3.10 \
        --use-standard-collections \
        --use-union-operator \
        --use-annotated \
        --disable-timestamp \
        --collapse-root-models \
        --field-constraints \
        --enum-field-as-literal one \
        --use-schema-description \
        --formatters ruff-format ruff-check
    expected="$(mktemp)"
    trap 'rm -f "$tmp" "$expected"' EXIT
    {
        printf '# @generated by `just sdk::python::openapi-gen` — DO NOT EDIT.\n'
        printf '# Source: packages/api-spec/openapi.json\n\n'
        tail -n +2 "$tmp"
    } > "$expected"
    if ! diff -u "{{ _generated }}" "$expected" >/dev/null; then
        echo "openapp_sdk/models/_generated.py is stale vs packages/api-spec/openapi.json." >&2
        echo "Run: just sdk::python::openapi-gen" >&2
        exit 1
    fi
    echo "openapp_sdk/models/_generated.py is up to date."

# Composite recipe used by `scripts/pre-commit-subproject-wrapper.sh packages/sdk-python`.
pre-commit: lint openapi-check test-unit
