T := dev/make_virtual_target

recursive_wildcard=$(foreach d, $(wildcard $(1:=/*)), $(call recursive_wildcard, $d, $2) $(filter $(subst *, %, $2), $d))

PACKAGE_JSONS := package.json
PACKAGE_JSONS += packages/backend/package.json
PACKAGE_JSONS += packages/backend-rs/package.json
PACKAGE_JSONS += packages/client/package.json
PACKAGE_JSONS += packages/firefish-js/package.json
PACKAGE_JSONS += packages/megalodon/package.json
PACKAGE_JSONS += packages/sw/package.json

RUST_DIR := packages/backend-rs
RUSTY_STUFF := $(call recursive_wildcard, $(RUST_DIR)/src, *)
RUSTY_STUFF += $(RUST_DIR)/Cargo.toml

MIGRATIONS := $(foreach dir, packages/backend/migration, $(wildcard $(dir)/*))
MIGRATIONS += $(foreach dir, packages/backend/migration-neko, $(wildcard $(dir)/*))

UPDATE_SCRIPTS := update.sh
UPDATE_SCRIPTS += $(foreach dir, neko/update, $(wildcard $(dir)/*))

POSTGRES_USER := firefish
POSTGRES_DB := firefish_db
POSTGRES_PASSWORD := password
POSTGRES_HOST_PORT := localhost:25432


.PHONY: pre-commit
pre-commit: test format shellcheck update-lockfiles regenerate-entities neko/index.js rust-lint


.PHONY: test
test: test-revert


.PHONY: test-revert
test-revert: $(T)/test-revert

$(T)/test-revert: neko/revert.sql $(MIGRATIONS)
	cd dev && \
	podman-compose exec db \
	  psql \
		--echo-all \
	    --user=$(POSTGRES_USER) \
		--dbname=$(POSTGRES_DB) \
		--set='ON_ERROR_STOP=1' \
		--command="$$(printf '%s\nROLLBACK;' "$$(cat ../neko/revert.sql | sed '$$ d')")"
	touch $@


.PHONY: update-lockfiles
update-lockfiles: pnpm-lock.yaml $(RUST_DIR)/Cargo.lock

pnpm-lock.yaml: pnpm-workspace.yaml $(PACKAGE_JSONS)
	pnpm install

$(RUST_DIR)/Cargo.lock: $(RUST_DIR)/Cargo.toml
	cd $(RUST_DIR) && cargo update


.PHONY: run
run:
	pnpm install
	pnpm run build:debug
	pnpm run migrate
	pnpm run start


.PHONY: shellcheck
shellcheck: $(T)/shellcheck

$(T)/shellcheck: $(UPDATE_SCRIPTS)
	shellcheck --external-sources $^
	touch $@


.PHONY: format
format:
	pnpm run format


.PHONY: rust-lint
rust-lint: $(T)/rust-lint

$(T)/rust-lint: $(RUSTY_STUFF)
	pnpm --filter='backend-rs' run lint
	touch $@


.PHONY: regenerate-entities
regenerate-entities: $(T)/regenerate-entities

$(T)/regenerate-entities: $(MIGRATIONS)
	pnpm run migrate
	cd $(RUST_DIR) && \
	sea-orm-cli generate entity \
	  --output-dir='src/model/entity' \
	  --database-url='postgres://$(POSTGRES_USER):$(POSTGRES_PASSWORD)@$(POSTGRES_HOST_PORT)/$(POSTGRES_DB)' \
	  --date-time-crate='chrono' \
	  --model-extra-attributes='NAPI_EXTRA_ATTR_PLACEHOLDER' && \
	for file in src/model/entity/*; do \
	  base=$$(basename -- "$${file}"); \
	  jsname=$$(printf '%s\n' "$${base%.*}" | perl -pe 's/(^|_)./uc($$&)/ge;s/_//g'); \
	  attribute=$$(printf 'napi_derive::napi(object, js_name = "%s")' "$${jsname}"); \
	  sed -i "s/NAPI_EXTRA_ATTR_PLACEHOLDER/$${attribute}/" "$${file}"; \
	done
	sed -i 's/#\[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum)\]/#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum)]\n#[napi_derive::napi]/' \
	  $(RUST_DIR)/src/model/entity/sea_orm_active_enums.rs
	touch $@


neko/index.js: $(RUSTY_STUFF)
	pnpm --filter='backend-rs' run build:debug
	[ -f $(RUST_DIR)/built/index.js ]
	rm neko/index.js
	cp $(RUST_DIR)/built/index.js neko/index.js


.PHONY: build-image
build-image:
	. neko/update/utils && \
	buildah build \
	  --no-cache \
	  --platform linux/amd64 \
	  --build-arg "VERSION=$$(version_ci)" \
	  --tag docker.io/naskya/firefish \
	  --tag registry.code.naskya.net/naskya/firefish \
	  --tag "registry.code.naskya.net/naskya/firefish:$$(version_ci | cut -d':' -f2)" \
	  .