-include .env

PHP_CONTAINER ?= mtc-pharmacy-web
DB_CONTAINER ?= mariadb
PROD_PATH ?= ~/public_html

.PHONY: start worktree worktree-rm admin-css-guard admin-js-guard admin-http-guard npm-build-admin npm-dev-admin

start:
	./start.sh

up:
	docker compose up -d

down:
	docker compose down

restart: down up

worktree:
	./scripts/worktree-create.sh

# Usage: make worktree-rm DIR=my-branch-dir [DELETE_BRANCH=1]
worktree-rm:
ifndef DIR
	$(error DIR is not set. Usage: make worktree-rm DIR=<dir-name> [DELETE_BRANCH=1])
endif
	./scripts/worktree-teardown.sh $(DIR) $(if $(DELETE_BRANCH),--delete-branch,)

shell:
	docker exec -it $(PHP_CONTAINER) bash

logs:
	docker compose logs -f

dump-autoload:
	docker exec -it $(PHP_CONTAINER) composer dump-autoload

migrate:
	docker exec -it $(PHP_CONTAINER) php artisan migrate

fresh:
	docker exec -it $(PHP_CONTAINER) php artisan migrate:fresh --seed
	docker exec -it $(PHP_CONTAINER) php artisan encryption:run

seed:
	docker exec -it $(PHP_CONTAINER) php artisan db:seed

view-routes:
	docker exec -it $(PHP_CONTAINER) php artisan route:list

new-migration:
	docker exec -it $(PHP_CONTAINER) php artisan make:migration

new-controller:
	docker exec -it $(PHP_CONTAINER) php artisan make:controller

new-model:
	docker exec -it $(PHP_CONTAINER) php artisan make:model

queue:
	docker exec -it $(PHP_CONTAINER) php artisan queue:work

cache:
	docker exec -it $(PHP_CONTAINER) php artisan cache:clear
	docker exec -it $(PHP_CONTAINER) php artisan config:clear
	docker exec -it $(PHP_CONTAINER) php artisan route:clear
	docker exec -it $(PHP_CONTAINER) php artisan view:clear
	docker exec -it $(PHP_CONTAINER) php artisan optimize:clear

composer-install:
	docker exec -it $(PHP_CONTAINER) composer install

composer-update:
	docker exec -it $(PHP_CONTAINER) composer update

npm-install:
	docker exec -it $(PHP_CONTAINER) npm install

npm-dev:
	docker exec -it $(PHP_CONTAINER) npm run dev

npm-prod:
	docker exec -it $(PHP_CONTAINER) npm run build

# One-off build of the admin bundle only, skipping the front-of-site build.
npm-build-admin:
	docker exec -it $(PHP_CONTAINER) npm run build:admin

# Watch mode for admin CSS and the admin Vue 2 SFCs.
#
# The admin bundle has no dev server - vite.admin.config.js is pinned to Vue 2
# and the front-of-site dev server would compile its SFCs with the Vue 3
# compiler - so `make npm-dev` does nothing for the admin. Without this, seeing
# a one-line change to mtc_admin_style.less would mean `make npm-prod`: the
# whole front-of-site bundle plus the admin bundle. Rebuilds are incremental
# and the page needs a plain refresh (no HMR).
npm-dev-admin:
	docker exec -it $(PHP_CONTAINER) npm run dev:admin

npm-clean:
	docker exec -it $(PHP_CONTAINER) rm -rf node_modules
	docker exec -it $(PHP_CONTAINER) rm package-lock.json

npm-clear-cache:
	docker exec -it $(PHP_CONTAINER) rm -rf node_modules/.vite

# Admin CSS is opt-in: every admin stylesheet must be declared in
# core/admin/css/imports_before.less or imports_after.less, or excluded with a
# stated reason. Deliberately no -it, so this runs in a pipeline or a hook.
admin-css-guard:
	docker exec $(PHP_CONTAINER) php scripts/admin_css_guard.php

# Admin JS is opt-in too: every admin script must be listed in
# core/admin/js/manifest.php, imported by core/admin/js/admin.js, or excluded
# with a stated reason. Deliberately no -it, so this runs in a pipeline or a hook.
admin-js-guard:
	docker exec $(PHP_CONTAINER) php scripts/admin_js_guard.php

# The admin has one HTTP client, core/admin/js/http.js. This fails on a declared
# admin script that reaches for a retired idiom instead. Deliberately no -it.
admin-http-guard:
	docker exec $(PHP_CONTAINER) php scripts/admin_http_guard.php


db-sync: db-pull db-reset-admin
	@echo "Database sync complete!"

db-wipe:
	@echo "Wiping local database $(DB_DATABASE)..."
	docker exec -i $(DB_CONTAINER) mariadb -uroot -p$(DB_PASSWORD) -e \
		"DROP DATABASE IF EXISTS $(DB_DATABASE); CREATE DATABASE $(DB_DATABASE); \
		 GRANT ALL ON $(DB_DATABASE).* TO '$(DB_USERNAME)'@'%'; FLUSH PRIVILEGES;"
	@echo "Local database wiped."

db-wipe-sync: db-wipe db-pull db-reset-admin
	@echo "Database wipe + sync complete!"

db-push-staging:
ifndef STAGING_HOST
	$(error STAGING_HOST is not set. Add STAGING_HOST, STAGING_USER, STAGING_DB_NAME, STAGING_DB_USER, STAGING_DB_PASS to .env)
endif
ifndef STAGING_USER
	$(error STAGING_USER is not set. Add STAGING_HOST, STAGING_USER, STAGING_DB_NAME, STAGING_DB_USER, STAGING_DB_PASS to .env)
endif
ifndef STAGING_DB_NAME
	$(error STAGING_DB_NAME is not set. Add STAGING_HOST, STAGING_USER, STAGING_DB_NAME, STAGING_DB_USER, STAGING_DB_PASS to .env)
endif
ifndef STAGING_DB_USER
	$(error STAGING_DB_USER is not set. Add STAGING_HOST, STAGING_USER, STAGING_DB_NAME, STAGING_DB_USER, STAGING_DB_PASS to .env)
endif
ifndef STAGING_DB_PASS
	$(error STAGING_DB_PASS is not set. Add STAGING_HOST, STAGING_USER, STAGING_DB_NAME, STAGING_DB_USER, STAGING_DB_PASS to .env)
endif
	@echo "WARNING: this OVERWRITES the staging database '$(STAGING_DB_NAME)' on $(STAGING_HOST)"
	@echo "         with your LOCAL database '$(DB_DATABASE)'. This cannot be undone."
	@read -p "Type 'yes' to continue: " confirm && [ "$$confirm" = "yes" ] || (echo "Aborted." && exit 1)
	@echo "Dumping local database and pushing to staging..."
	@echo "This may take a few minutes depending on database size."
	@bash -c "set -o pipefail; docker exec -i $(DB_CONTAINER) mariadb-dump --no-tablespaces --skip-triggers -u $(DB_USERNAME) -p$(DB_PASSWORD) $(DB_DATABASE) | sed 's/DEFINER=[^*]*\*/\*/g' | ssh $(STAGING_USER)@$(STAGING_HOST) \"mysql -u $(STAGING_DB_USER) -p'$(STAGING_DB_PASS)' $(STAGING_DB_NAME)\""
	@echo "Staging database replaced with local!"

ssh-staging:
ifndef STAGING_HOST
	$(error STAGING_HOST is not set. Add STAGING_HOST, STAGING_USER to .env)
endif
	ssh -t $(STAGING_USER)@$(STAGING_HOST) "exec \$$SHELL -l"

ssh-live:
ifndef PROD_HOST
	$(error PROD_HOST is not set. Add PROD_HOST, PROD_USER to .env)
endif
	ssh -t $(PROD_USER)@$(PROD_HOST) "cd $(PROD_PATH) && exec \$$SHELL -l"

db-pull:
ifndef PROD_HOST
	$(error PROD_HOST is not set. Add PROD_HOST, PROD_USER, PROD_DB_NAME, PROD_DB_USER, PROD_DB_PASS to .env)
endif
	@echo "Pulling database from production..."
	@echo "This may take a few minutes depending on database size."
	ssh $(PROD_USER)@$(PROD_HOST) "mysqldump --no-tablespaces --skip-triggers -u $(PROD_DB_USER) -p'$(PROD_DB_PASS)' $(PROD_DB_NAME)" | sed 's/DEFINER=[^*]*\*/\*/g' | docker exec -i $(DB_CONTAINER) mariadb -u $(DB_USERNAME) -p$(DB_PASSWORD) $(DB_DATABASE)

db-reset-admin:
	@echo "Re-seeding admin user for local dev..."
	docker exec $(PHP_CONTAINER) php artisan db:seed --class=AdminUsersTableSeeder
	@echo "Running encryption to generate hashes..."
	docker exec $(PHP_CONTAINER) php artisan encryption:run

blocks-import:
	@docker exec -i $(PHP_CONTAINER) php artisan blocks:import --all --force

admin-tabs-regen:
	@docker exec -i $(PHP_CONTAINER) php scripts/generate_admin_mtc_tabs.php

db-diff:
ifndef PROD_HOST
	$(error PROD_HOST is not set. Add PROD_HOST, PROD_USER, PROD_DB_NAME, PROD_DB_USER, PROD_DB_PASS to .env)
endif
	@echo "Comparing local vs production database schema..."
	@docker exec $(DB_CONTAINER) mariadb -u $(DB_USERNAME) -p$(DB_PASSWORD) $(DB_DATABASE) -N -e "SHOW TABLES" | sort > /tmp/local_tables.txt
	@ssh $(PROD_USER)@$(PROD_HOST) "mysql -u $(PROD_DB_USER) -p'$(PROD_DB_PASS)' $(PROD_DB_NAME) -N -e 'SHOW TABLES'" | sort > /tmp/prod_tables.txt
	@echo "=== Tables only in LOCAL ==="
	@comm -23 /tmp/local_tables.txt /tmp/prod_tables.txt || true
	@echo ""
	@echo "=== Tables only in PRODUCTION ==="
	@comm -13 /tmp/local_tables.txt /tmp/prod_tables.txt || true
	@rm -f /tmp/local_tables.txt /tmp/prod_tables.txt

blocks-regen-images:
	@docker exec -i $(PHP_CONTAINER) php artisan blocks:regenerate-images
