set allow-duplicate-recipes := true
set allow-duplicate-variables := true
set shell := ["bash", "-euo", "pipefail", "-c"]

# ---------------------------------------------------------------------------- #
#                                 DEPENDENCIES                                 #
# ---------------------------------------------------------------------------- #

# Rust: https://rust-lang.org/tools/install
cargo := require("cargo")
rustc := require("rustc")

# ---------------------------------------------------------------------------- #
#                                    RECIPES                                   #
# ---------------------------------------------------------------------------- #

# Show available commands
default:
    @just --list

# Build the program
build:
    cargo build

# Run the program
run:
    cargo run

# Check code formatting
format-check:
    cargo fmt --all --check

# Format code
format:
    cargo fmt --all
alias fmt := format

# Run clippy lints
lint:
    cargo clippy -- --deny warnings

# Run all code checks
full-check: format-check lint
alias fc := full-check

# Fix formatting (alias for format)
full-write: format
alias fw := full-write

# Run tests
test:
    cargo test

# Run the same checks CI runs locally (full-check + tests)
ci: full-check test

# Build API docs (no deps)
doc:
    cargo doc --no-deps

# Build API docs and open in the browser
doc-open:
    cargo doc --no-deps --open

# List dependencies with newer versions available (requires cargo-outdated)
outdated:
    cargo outdated

# Check dependencies for known security advisories (requires cargo-audit)
audit:
    cargo audit

# Install optional cargo tools used by other recipes (cargo-outdated, cargo-audit)
install-tools:
    cargo install --locked cargo-outdated cargo-audit

# ---------------------------------------------------------------------------- #
#                                   RELEASE                                    #
# ---------------------------------------------------------------------------- #

# Generate changelog from conventional commits
changelog:
    git-cliff --output CHANGELOG.md

# Check for semver violations against the latest git tag
semver-check:
    cargo semver-checks --baseline-rev "$(git describe --tags --abbrev=0)"

# Dry-run a release (default: patch bump)
release-dry-run level="patch":
    cargo release {{level}} --no-confirm

# Perform a release (patch, minor, or major)
release level="patch":
    cargo release {{level}} --execute

# ---------------------------------------------------------------------------- #
#                               QUALITY CHECK                                  #
# ---------------------------------------------------------------------------- #

# Run checks with AI-powered auto-fix (dry-run by default; --execute to run)
quality-check *args:
    bash scripts/quality_check.sh {{args}}
alias qc := quality-check

# ---------------------------------------------------------------------------- #
#                                  TEMPLATE                                    #
# ---------------------------------------------------------------------------- #

# Bring repo up to date with upstream template (dry-run by default; --execute to run, optional target dir)
bring-up-to-date *args:
    bash scripts/bring_up_to_date.sh {{args}}
alias butd := bring-up-to-date

# Bring all projects in downstream.txt up to date in parallel (dry-run by default; --execute to run)
bring-up-to-date-all *args:
    bash scripts/bring_up_to_date_all.sh {{args}}
alias butda := bring-up-to-date-all

# ---------------------------------------------------------------------------- #
#                               CARGO UPDATE                                   #
# ---------------------------------------------------------------------------- #

# Update cargo dependencies, run checks, and open a PR (dry-run by default; --execute to run, optional target dir)
cargo-update *args:
    bash scripts/cargo_update.sh {{args}}
alias cu := cargo-update

# Update cargo dependencies in all downstream projects in parallel (dry-run by default; --execute to run)
cargo-update-all *args:
    bash scripts/cargo_update_all.sh {{args}}
alias cua := cargo-update-all

# ---------------------------------------------------------------------------- #
#                             TEMPLATE REVIEW                                  #
# ---------------------------------------------------------------------------- #

# Review a downstream project for improvements to backport into the template (dry-run by default; --execute to run, optional target dir)
template-review *args:
    bash scripts/template_review.sh {{args}}
alias tr := template-review

# Review all downstream projects in parallel for backport candidates (dry-run by default; --execute to run)
template-review-all *args:
    bash scripts/template_review_all.sh {{args}}
alias tra := template-review-all

# ---------------------------------------------------------------------------- #
#                            TEMPLATE BACKPORT                                 #
# ---------------------------------------------------------------------------- #

# Backport improvements from a downstream project into a fresh template clone and open a PR (dry-run by default; --execute to run)
template-backport *args:
    bash scripts/template_backport.sh {{args}}
alias tb := template-backport

# Backport improvements from all downstream projects, one PR each (dry-run by default; --execute to run)
template-backport-all *args:
    bash scripts/template_backport_all.sh {{args}}
alias tba := template-backport-all

# ---------------------------------------------------------------------------- #
#                                   COUSINS                                    #
# ---------------------------------------------------------------------------- #

# Review one cousin repo (by name from scripts/cousins.json) for template-sourced improvements (dry-run by default; --execute to run)
cousin-review *args:
    bash scripts/cousin_review.sh {{args}}
alias cr := cousin-review

# Review every cousin in scripts/cousins.json in parallel (dry-run by default; --execute to run)
cousin-review-all *args:
    bash scripts/cousin_review_all.sh {{args}}
alias cra := cousin-review-all

# Apply template-sourced changes to a cousin's opted-in paths and open a PR (dry-run by default; --execute to run)
cousin-apply *args:
    bash scripts/cousin_apply.sh {{args}}
alias ca := cousin-apply

# Apply changes to every cousin, one PR each (dry-run by default; --execute to run)
cousin-apply-all *args:
    bash scripts/cousin_apply_all.sh {{args}}
alias caa := cousin-apply-all
