# Gotham — build & deploy helpers (.so plugin workflow)
#
# The plugin compiles to a .so shared object loaded by the CMS at runtime.
# `make rebuild` copies source to the container, builds the .so, and restarts.
#
# Usage:
#   make rebuild       # Full rebuild: frontend + .so + CSS + migrations, restart
#   make backend       # Build .so + migrations, restart
#   make build-css     # Rebuild Tailwind CSS
#   make logs          # Tail instance logs
#   make status        # Show instance container status

.PHONY: rebuild backend build-frontend build-base-binary build-so copy-plugin-source sync-migrations build-css deploy-css logs status help spinup templ bump-patch bump-minor bump-major sync-version

# Paths
BLOCKNINJA_DIR  := $(HOME)/src/blockninja
PLUGIN_SRC      := $(CURDIR)
PLUGIN_NAME     := gotham
MIGRATIONS_SRC  := $(BLOCKNINJA_DIR)/backend/sql/migrations
GO_BUILDER      := localhost/blockninja-go-builder:latest
CONTAINER       := instance-gotham
ACCOUNT_SLUG    := blockninja
INSTANCE_SLUG   := gotham
STYLES_DIR      := /var/lib/blockninja/$(ACCOUNT_SLUG)/$(INSTANCE_SLUG)/styles
PLUGIN_DEST     := /app/data/plugins/src/$(PLUGIN_NAME)

# Default target: build the .so locally for development.
all: $(PLUGIN_NAME).so

# Local plugin build (no container). Useful for CI / quick checks.
$(PLUGIN_NAME).so: $(wildcard *.go) plugin.mod go.mod
	CGO_ENABLED=1 go build -buildmode=plugin -ldflags="-s -w" -o $(PLUGIN_NAME).so .

# Ensure blockninja core services and the instance container are running.
spinup:
	$(MAKE) -C $(BLOCKNINJA_DIR) spinup

# Full rebuild: frontend + .so plugin + CSS + migrations, restart.
rebuild: spinup
	$(MAKE) build-frontend
	$(MAKE) build-base-binary
	$(MAKE) copy-plugin-source
	$(MAKE) build-so
	$(MAKE) build-css
	$(MAKE) sync-migrations
	podman restart $(CONTAINER)
	@sleep 2
	$(MAKE) deploy-css
	@echo ""
	@echo "Done. https://$(INSTANCE_SLUG).localdev.blockninjacms.com/"

# Backend-only rebuild: .so plugin + migrations, restart.
backend: spinup
	$(MAKE) build-base-binary
	$(MAKE) copy-plugin-source
	$(MAKE) build-so
	$(MAKE) sync-migrations
	podman restart $(CONTAINER)
	@echo "Backend updated."

# Build host admin UI and deploy to container.
build-frontend:
	@echo "==> Building @block-ninja/ui ..."
	cd $(BLOCKNINJA_DIR)/packages/ui && pnpm run build
	@echo "==> Building host admin UI ..."
	cd $(BLOCKNINJA_DIR)/web && pnpm run build
	@echo "==> Deploying frontend to container ..."
	podman exec $(CONTAINER) rm -rf /app/web/dist
	podman cp $(BLOCKNINJA_DIR)/web/dist $(CONTAINER):/app/web/dist
	@echo "Frontend deployed."

# Build the base CMS binary (without external plugins) and copy to container.
build-base-binary:
	@echo "==> Building base CMS binary ..."
	podman run --rm \
		-v $(BLOCKNINJA_DIR)/backend:/src/backend:ro \
		-v blockninja_go_cache:/go/pkg/mod \
		-v /tmp:/out \
		-w /src/backend \
		$(GO_BUILDER) \
		go build -o /out/blockninja-server ./cmd/server
	podman cp /tmp/blockninja-server $(CONTAINER):/app/server
	rm -f /tmp/blockninja-server

# Copy plugin source into the container's plugin source directory.
copy-plugin-source:
	@echo "==> Copying $(PLUGIN_NAME) source to container ..."
	podman exec $(CONTAINER) rm -rf $(PLUGIN_DEST)
	podman exec $(CONTAINER) mkdir -p $(PLUGIN_DEST)
	podman cp $(PLUGIN_SRC)/. $(CONTAINER):$(PLUGIN_DEST)/
	podman exec $(CONTAINER) rm -rf $(PLUGIN_DEST)/.git $(PLUGIN_DEST)/Makefile
	@echo "Plugin source copied."

# Build the .so using the go-builder container (same toolchain as CMS binary).
# Both builds resolve block/core from the shared module cache — no local replace.
build-so:
	@echo "==> Building $(PLUGIN_NAME).so ..."
	podman run --rm \
		-v $(PLUGIN_SRC):/src/plugin:ro \
		-v blockninja_go_cache:/go/pkg/mod \
		-v /tmp:/out \
		-w /src/plugin \
		-e CGO_ENABLED=1 \
		$(GO_BUILDER) \
		go build -buildmode=plugin -ldflags="-s -w" -o /out/$(PLUGIN_NAME).so .
	podman exec $(CONTAINER) mkdir -p /app/data/plugins/so
	podman cp /tmp/$(PLUGIN_NAME).so $(CONTAINER):/app/data/plugins/so/$(PLUGIN_NAME).so
	rm -f /tmp/$(PLUGIN_NAME).so
	@echo "$(PLUGIN_NAME).so built."

# Sync base blockninja migration files from host to container.
sync-migrations:
	@echo "==> Syncing migrations ..."
	@podman unshare bash -c ' \
		M=$$(podman mount $(CONTAINER)) && \
		rm -rf "$$M/app/migrations" && \
		mkdir -p "$$M/app/migrations" && \
		podman umount $(CONTAINER)'
	@podman cp $(MIGRATIONS_SRC)/. $(CONTAINER):/app/migrations/
	@echo "Migrations synced."

# Rebuild Tailwind CSS.
build-css:
	@echo "==> Building CSS ..."
	cd $(BLOCKNINJA_DIR) && make css

# Copy built CSS to instance styles dir and container.
deploy-css:
	@mkdir -p $(STYLES_DIR)
	cp $(BLOCKNINJA_DIR)/data/styles/styles.css $(STYLES_DIR)/styles.css
	podman cp $(BLOCKNINJA_DIR)/data/styles/styles.css $(CONTAINER):/app/data/styles/styles.css
	podman cp $(BLOCKNINJA_DIR)/styles/input.base.css $(CONTAINER):/app/styles/input.base.css
	@echo "CSS deployed."

# Regenerate templ Go files locally (for development).
templ:
	cd $(PLUGIN_SRC) && templ generate

# Tail instance logs.
logs:
	podman logs -f $(CONTAINER)

# Show instance container status.
status:
	@podman inspect $(CONTAINER) --format \
		'Name:    {{.Name}}\nImage:   {{.Config.Image}}\nStatus:  {{.State.Status}}\nHealth:  {{.State.Health.Status}}\nStarted: {{.State.StartedAt}}' \
		2>/dev/null || echo "Container $(CONTAINER) not found."

help:
	@echo "Targets:"
	@echo "  all                  Build $(PLUGIN_NAME).so locally (default)"
	@echo "  spinup               Start blockninja core services + instance container if stopped"
	@echo "  rebuild              Full rebuild: frontend + .so + CSS + migrations, restart"
	@echo "  backend              Build .so + migrations, restart"
	@echo "  build-frontend       Build host admin UI, deploy to container"
	@echo "  build-base-binary    Build base CMS binary, copy to container"
	@echo "  copy-plugin-source   Copy plugin source into container"
	@echo "  build-so             Build .so inside container"
	@echo "  sync-migrations      Copy migration files from host to container"
	@echo "  build-css            Rebuild Tailwind CSS"
	@echo "  deploy-css           Copy CSS to instance styles dir"
	@echo "  templ                Regenerate templ Go files locally"
	@echo "  logs                 Tail instance container logs"
	@echo "  status               Show instance container status"

# --- Version bump targets ---
CURRENT_VERSION := $(shell grep '^version' plugin.mod | sed 's/.*"\(.*\)"/\1/')

bump-patch:
	@NEW=$$(echo $(CURRENT_VERSION) | awk -F. '{printf "%d.%d.%d", $$1, $$2, $$3+1}'); \
	sed -i 's/version = "$(CURRENT_VERSION)"/version = "'$$NEW'"/' plugin.mod; \
	git add plugin.mod && git commit -m "chore: bump version to $$NEW" && git tag "v$$NEW"; \
	echo "Bumped to $$NEW and tagged v$$NEW"

bump-minor:
	@NEW=$$(echo $(CURRENT_VERSION) | awk -F. '{printf "%d.%d.0", $$1, $$2+1}'); \
	sed -i 's/version = "$(CURRENT_VERSION)"/version = "'$$NEW'"/' plugin.mod; \
	git add plugin.mod && git commit -m "chore: bump version to $$NEW" && git tag "v$$NEW"; \
	echo "Bumped to $$NEW and tagged v$$NEW"

bump-major:
	@NEW=$$(echo $(CURRENT_VERSION) | awk -F. '{printf "%d.0.0", $$1+1}'); \
	sed -i 's/version = "$(CURRENT_VERSION)"/version = "'$$NEW'"/' plugin.mod; \
	git add plugin.mod && git commit -m "chore: bump version to $$NEW" && git tag "v$$NEW"; \
	echo "Bumped to $$NEW and tagged v$$NEW"

sync-version:
	@TAG=$$(git describe --tags --abbrev=0 2>/dev/null | sed 's/^v//'); \
	if [ -z "$$TAG" ]; then echo "No tags found"; exit 1; fi; \
	sed -i 's/version = "$(CURRENT_VERSION)"/version = "'$$TAG'"/' plugin.mod; \
	echo "Synced plugin.mod to $$TAG"
