FRONTEND_SOURCES := $(shell find frontend/src frontend/css -type f)

all: src/fava/static/app.js

# Compile the frontend.
src/fava/static/app.js: $(FRONTEND_SOURCES) frontend/build.ts frontend/node_modules
	cd frontend; npm run build

# Install the frontend node_modules dependencies.
frontend/node_modules: frontend/package-lock.json
	cd frontend; npm install --no-progress
	touch -m frontend/node_modules

# Create and sync a dev environment.
.PHONY: dev
dev: .venv
.venv: constraints.txt requirements.txt pyproject.toml
	uv venv --allow-existing
	uv pip sync requirements.txt
	touch -m .venv

# Remove the generated frontend and translations in addition to mostlyclean (see below).
.PHONY: clean
clean: mostlyclean
	find src/fava/static ! -name 'favicon.ico' -type f -exec rm -f {} +
	find src/fava/translations -name '*.mo' -delete

# Remove node_modules, caches, .tox, etc.
.PHONY: mostlyclean
mostlyclean:
	rm -rf .*cache
	rm -rf .eggs
	rm -rf .tox
	rm -rf .venv
	rm -rf build
	rm -rf dist
	rm -rf htmlcov
	rm -rf frontend/node_modules
	find . -type f -name '*.py[c0]' -delete
	find . -type d -name "__pycache__" -delete

# Run linters.
.PHONY: lint
lint: frontend/node_modules
	pre-commit run -a
	cd frontend; npm exec tsc
	cd frontend; npm exec svelte-check
	tox -e lint

# Run tests.
.PHONY: test
test: frontend/node_modules
	cd frontend; npm run test
	tox -e py

# Update the snapshot files generated by the snapshot tests.
.PHONY: update-snapshots
update-snapshots:
	find . -name "__snapshots__" -type d -prune -exec rm -r "{}" +
	-SNAPSHOT_UPDATE=1 tox -e py
	tox -e py

# Update the constraints file for Python dependencies
.PHONY: update-constraints
update-constraints:
	uv pip compile --quiet --extra excel --extra dev --python-version 3.9 --upgrade --output-file constraints.txt pyproject.toml
	uv pip compile --quiet --extra excel --extra old_deps_pins --resolution=lowest --python-version 3.9 --upgrade --output-file constraints-old.txt pyproject.toml

# Update the frontend dependencies.
.PHONY: update-frontend-deps
update-frontend-deps:
	-cd frontend; npm outdated
	cd frontend; npm update
	cd frontend; npm run sync-pre-commit
	touch -m frontend/node_modules

# Update pre-commit hooks
.PHONY: update-precommit
update-precommit:
	pre-commit autoupdate

# Update frontend deps, Python deps and pre-commit
.PHONY: update
update: update-constraints update-frontend-deps update-precommit

# Build the website
.PHONY: docs
docs:
	tox -e docs

# Run fava for the example files.
.PHONY: run-example
run-example:
	@xdg-open http://localhost:3333
	BEANCOUNT_FILE= fava -p 3333 --debug tests/data/*.beancount

# Generate the bql-grammar json file used by the frontend.
.PHONY: bql-grammar
bql-grammar: .venv contrib/scripts.py constraints.txt
	uv run --no-sync python contrib/scripts.py generate-bql-grammar-json
	-pre-commit run prettier --files frontend/src/codemirror/bql-grammar.ts

# Build the distribution (sdist and wheel).
.PHONY: dist
dist:
	rm -rf dist/*.tar.gz
	rm -rf dist/*.whl
	python -m build
	twine check dist/*

# Build the bql-grammar and update translations with POEditor.com
.PHONY: before-release
before-release: bql-grammar translations-push translations-fetch

# Extract translation strings.
.PHONY: translations-extract
translations-extract: .venv
	uv run --no-sync pybabel extract -F src/fava/translations/babel.conf -o src/fava/translations/messages.pot .

# Extract translation strings and upload them to POEditor.com.
# Requires the environment variable POEDITOR_TOKEN to be set to an API token
# for POEditor.
.PHONY: translations-push
translations-push: .venv translations-extract
	uv run --no-sync python contrib/scripts.py upload-translations

# Download translations from POEditor.com. (also requires POEDITOR_TOKEN)
.PHONY: translations-fetch
translations-fetch: .venv
	uv run --no-sync python contrib/scripts.py download-translations

# Create a binary using pyinstaller
dist/fava: src/fava/static/app.js
	tox -e pyinstaller
