# Xtablo backend — task runner
#
# Portability: compose.yaml works under both `podman compose` and `docker compose` (CONTEXT D-11).
# This justfile uses `podman compose` by default; substitute `docker compose` if needed —
# the service definition is identical.
#
# Dev workflow (two terminals, per RESEARCH Open Question 2):
#   Terminal 1:  just dev            # brings up postgres, generates assets, runs air for Go live-reload
#   Terminal 2:  just styles-watch   # runs the Tailwind standalone CLI in --watch mode
#
# Tailwind is intentionally NOT chained into air's pre_cmd: piping CSS rebuilds through
# every .go save is wasteful, and the two concerns are independent (CONTEXT D-14).

set shell := ["bash", "-cu"]

# --- Pinned versions ------------------------------------------------------------------------
# Runtime Go modules are pinned in go.mod (chi v5.2.5, templ v0.3.1020, pgx/v5 v5.9.2,
# goose v3.27.1, uuid v1.6.0). Below: CLI tools installed by `just bootstrap`.
goose_version    := "v3.27.1"
templ_version    := "v0.3.1020"
sqlc_version     := "v1.31.1"
air_version      := "v1.65.1"
# Tailwind standalone CLI version pinned for reproducible bootstrap. Update by bumping
# this string after verifying the release at https://github.com/tailwindlabs/tailwindcss/releases
tailwind_version := "v4.0.0"
# HTMX version pinned at bootstrap time. This is the SINGLE authoritative source for the
# HTMX version — no runtime CDN reference appears anywhere else (CONTEXT D-10).
htmx_version     := "2"

# --- Local config ---------------------------------------------------------------------------
database_url := "postgres://xtablo:xtablo@localhost:5432/xtablo?sslmode=disable"
tailwind     := "./bin/tailwindcss"

default:
  @just --list

# Install all CLI tools and bootstrap-download Tailwind + HTMX into local paths.
# Network access required. All downloaded artifacts are gitignored — `just bootstrap` is the
# canonical reproduction step.
bootstrap:
  mkdir -p bin static
  # 1. Go-based CLI tools (versions pinned above)
  go install github.com/pressly/goose/v3/cmd/goose@{{goose_version}}
  go install github.com/a-h/templ/cmd/templ@{{templ_version}}
  go install github.com/sqlc-dev/sqlc/cmd/sqlc@{{sqlc_version}}
  go install github.com/air-verse/air@{{air_version}}
  # 2. Tailwind standalone CLI — explicit OS/arch mapping. The Tailwind release artifacts
  # use 'macos'/'linux' and 'x64'/'arm64', which do NOT match raw `uname -s` / `uname -m`
  # output (darwin vs macos, x86_64 vs x64). Resolve via case (Codex review concern #2).
  # Resolves to one of: tailwindcss-macos-x64, tailwindcss-macos-arm64,
  #                    tailwindcss-linux-x64, tailwindcss-linux-arm64
  os_name=$(uname -s); \
  arch_name=$(uname -m); \
  case "$os_name" in \
    Darwin) tw_os=macos ;; \
    Linux)  tw_os=linux ;; \
    *) echo "Unsupported OS: $os_name (Tailwind standalone supports macos/linux)"; exit 1 ;; \
  esac; \
  case "$arch_name" in \
    x86_64|amd64) tw_arch=x64 ;; \
    arm64|aarch64) tw_arch=arm64 ;; \
    *) echo "Unsupported arch: $arch_name"; exit 1 ;; \
  esac; \
  asset="tailwindcss-${tw_os}-${tw_arch}"; \
  echo "Downloading $asset @ {{tailwind_version}}"; \
  curl -sSL -o bin/tailwindcss \
    "https://github.com/tailwindlabs/tailwindcss/releases/download/{{tailwind_version}}/${asset}"; \
  chmod +x bin/tailwindcss
  # 3. HTMX — bootstrap-time download. This unpkg URL is the explicit allowed exception to
  # the runtime no-CDN rule (CONTEXT D-10); served HTML references only /static/htmx.min.js.
  curl -sSL -o static/htmx.min.js "https://unpkg.com/htmx.org@{{htmx_version}}/dist/htmx.min.js"

db-up:
  podman compose up -d postgres

db-down:
  podman compose down

# `just migrate up`, `just migrate down`, `just migrate status`, etc.
migrate cmd="status":
  GOOSE_DRIVER=postgres GOOSE_DBSTRING='{{database_url}}' GOOSE_MIGRATION_DIR=migrations \
    goose {{cmd}}

# templ → Go, sqlc → Go, tailwind → static/tailwind.css. Consumers (templ files, queries,
# ui CSS) land in Plans 01-02 / 01-03; until then this recipe will fail when invoked but
# its declaration is the contract.
generate:
  templ generate
  sqlc generate
  {{tailwind}} -i tailwind.input.css -o static/tailwind.css

styles-watch:
  {{tailwind}} -i tailwind.input.css -o static/tailwind.css --watch

dev: db-up
  just generate
  DATABASE_URL='{{database_url}}' air -c .air.toml

test:
  just generate
  go test ./...

lint:
  go vet ./...
  gofmt -l . | (grep . && exit 1 || exit 0)

build:
  just generate
  go build -o bin/web ./cmd/web
  go build -o bin/worker ./cmd/worker

# Remove all bootstrap-downloaded and generated artifacts. Does NOT touch the Postgres
# volume — run `just db-down` first if a full reset is needed.
clean:
  rm -rf bin/ tmp/ static/htmx.min.js static/tailwind.css
  find . -name '*_templ.go' -delete
