COMPOSE ?= docker compose
COMPOSE_INIT := $(COMPOSE) --profile init

MIGRATE := proxmox-migrate ovirt-migrate vmware-migrate openstack-migrate
SEED := proxmox-seed ovirt-seed vmware-seed openstack-seed
APPS := postgres proxmox ovirt vmware openstack ovirt-gateway vmware-gateway openstack-gateway

CHART ?= charts/api-simulators-lab
HELM_RELEASE ?= simulators
# Prefer values.yaml namespace; override with: make helm-up HELM_NAMESPACE=other
HELM_NAMESPACE ?= $(shell awk '/^namespace:/{print $$2; exit}' $(CHART)/values.yaml)

# Second word for: make helm up | make helm down
ifeq (helm,$(firstword $(MAKECMDGOALS)))
HELM_CMD := $(word 2,$(MAKECMDGOALS))
endif

.PHONY: up down clean restart logs shell pull ps urls help init-clean \
	helm helm-up helm-down helm-template helm-lint helm-urls \
	helm-install helm-uninstall push

help: ## Show targets
	@echo "Compose:"
	@awk 'BEGIN {FS = ":.*?## "} /^(up|down|clean|restart|logs|shell|pull|ps|urls|init-clean):.*?## / {printf "  %-16s %s\n", $$1, $$2}' $(MAKEFILE_LIST)
	@echo ""
	@echo "Helm (make helm up | make helm down):"
	@awk 'BEGIN {FS = ":.*?## "} /^helm(-[a-zA-Z0-9]+)?:.*?## / {printf "  %-16s %s\n", $$1, $$2}' $(MAKEFILE_LIST)
	@echo ""
	@echo "Other:"
	@awk 'BEGIN {FS = ":.*?## "} /^(help|push):.*?## / {printf "  %-16s %s\n", $$1, $$2}' $(MAKEFILE_LIST)

up: ## Compose: pull, migrate, start apps, seed
ifdef HELM_CMD
	@:
else
	$(COMPOSE) pull
	$(COMPOSE) up -d postgres
	$(COMPOSE) up -d --wait postgres
	@echo ">> migrate"
	@set -e; for s in $(MIGRATE); do \
		echo "  $$s"; \
		$(COMPOSE_INIT) run --rm --no-deps $$s; \
	done
	@echo ">> apps + gateways"
	$(COMPOSE) up -d --wait $(APPS)
	@echo ">> seed"
	@set -e; for s in $(SEED); do \
		echo "  $$s"; \
		$(COMPOSE_INIT) run --rm --no-deps $$s; \
	done
	@$(MAKE) init-clean
	@echo "Stack is up (migrate/seed containers removed)."
	@$(MAKE) --no-print-directory urls
endif

urls: ## Compose: print simulator URLs
	@printf '\nEndpoints:\n'
	@printf '  %-22s %s\n' 'Proxmox' 'http://localhost:8006/'
	@printf '  %-22s %s\n' 'oVirt Engine' 'https://localhost:7443/'
	@printf '  %-22s %s\n' 'oVirt Web UI' 'http://localhost:7500/'
	@printf '  %-22s %s\n' 'VMware (HTTPS)' 'https://localhost:8443/'
	@printf '  %-22s %s\n' 'VMware (HTTP)' 'http://localhost:8081/'
	@printf '  %-22s %s\n' 'OpenStack Keystone' 'http://localhost:9500/'
	@printf '  %-22s %s\n' 'OpenStack Nova' 'http://localhost:8774/'
	@printf '  %-22s %s\n' 'OpenStack HTTPS' 'https://localhost:9443/'
	@printf '  %-22s %s\n' 'PostgreSQL' '127.0.0.1:5432 (lab / lab)'
	@printf '\n'

init-clean: ## Compose: remove leftover migrate/seed containers
	-$(COMPOSE_INIT) rm -f $(MIGRATE) $(SEED) 2>/dev/null
	-@ids=$$(docker ps -aq --filter "label=com.docker.compose.project=api-simulators-lab" \
		--filter "name=migrate" --filter "name=seed" 2>/dev/null); \
		[ -z "$$ids" ] || docker rm -f $$ids 2>/dev/null || true

down: ## Compose: stop and remove containers (keep DB volume)
ifdef HELM_CMD
	@:
else
	$(COMPOSE_INIT) down --remove-orphans
endif

clean: ## Compose: stop stack and remove volumes / leftovers
	$(COMPOSE_INIT) down -v --remove-orphans
	@$(MAKE) init-clean
	-@nets=$$(docker network ls -q --filter "label=com.docker.compose.project=api-simulators-lab" 2>/dev/null); \
		[ -z "$$nets" ] || docker network rm $$nets 2>/dev/null || true
	@echo "Stack cleaned (containers, volumes, leftover init)."

restart: ## Compose: restart app services
	$(COMPOSE) restart $(filter-out postgres,$(APPS))

logs: ## Compose: follow logs (SERVICE=proxmox optional)
	$(COMPOSE) logs -f --tail=200 $(SERVICE)

shell: ## Compose: shell into a service (SERVICE=proxmox default)
	$(COMPOSE) exec $(or $(SERVICE),proxmox) bash || \
		$(COMPOSE) exec $(or $(SERVICE),proxmox) sh

pull: ## Compose: pull Hub images only
	$(COMPOSE) pull

ps: ## Compose: show container status
	$(COMPOSE) ps -a

# ── Helm ──────────────────────────────────────────────────

helm: ## Dispatcher: make helm up | make helm down
	@case "$(HELM_CMD)" in \
	  up) $(MAKE) helm-up ;; \
	  down) $(MAKE) helm-down ;; \
	  "") echo "Usage: make helm up | make helm down"; exit 1 ;; \
	  *) echo "Unknown: make helm $(HELM_CMD)"; echo "Usage: make helm up | make helm down"; exit 1 ;; \
	esac

helm-up: ## Helm: deploy chart (warns + asks confirmation)
	@printf '\n'
	@printf 'WARNING: Configure Helm values before deploying to the cluster.\n'
	@printf '  File: %s/values.yaml\n' '$(CHART)'
	@printf '  Review at least:\n'
	@printf '    - namespace, ingresses, certManager\n'
	@printf '    - imageTag, ticketSigningKey, imagePullSecrets\n'
	@printf '    - postgres.persistence (size, storageClass)\n'
	@printf '  Let'\''s Encrypt needs public DNS to the Ingress (not *.lab.local).\n'
	@printf '  Release:   %s\n' '$(HELM_RELEASE)'
	@printf '  Namespace: %s (from values.namespace)\n' '$(HELM_NAMESPACE)'
	@printf '\n'
ifeq ($(HELM_YES),1)
	@echo "HELM_YES=1 — skipping confirmation."
else
	@printf 'Values are configured and it is OK to deploy? [y/N] '
	@read ans; \
	case "$$ans" in \
	  y|Y|yes|YES) ;; \
	  *) echo "Aborted."; exit 1 ;; \
	esac
endif
	helm upgrade --install $(HELM_RELEASE) $(CHART) \
		--namespace $(HELM_NAMESPACE) --create-namespace --wait \
		--set namespace=$(HELM_NAMESPACE)
	@$(MAKE) --no-print-directory helm-urls

helm-down: ## Helm: uninstall release
	helm uninstall $(HELM_RELEASE) --namespace $(HELM_NAMESPACE) || true
	@echo "Helm release $(HELM_RELEASE) removed from namespace $(HELM_NAMESPACE)."

helm-install: helm-up ## Alias of helm-up

helm-uninstall: helm-down ## Alias of helm-down

helm-template: ## Helm: render manifests
	helm template $(HELM_RELEASE) $(CHART) --namespace $(HELM_NAMESPACE)

helm-lint: ## Helm: lint chart
	helm lint $(CHART)

helm-urls: ## Helm: print Ingress hosts from values
	@printf '\nIngress hosts (TLS / Let'\''s Encrypt):\n'
	@awk '\
	  /^ingresses:/{p=1; next} \
	  p && /^[^ #\t]/{exit} \
	  p && /^  [a-zA-Z0-9_-]+:/{name=$$1; sub(/:/,"",name)} \
	  p && /^    host:/{host=$$2; printf "  %-16s https://%s/\n", name, host} \
	' $(CHART)/values.yaml
	@printf '\n'

push: ## git add ., multiline commit (Ctrl-D), push origin
	@set -e; \
	git add .; \
	echo "=== staged ==="; \
	git status --short; \
	echo; \
	if git diff --cached --quiet; then \
		echo "Nothing to commit — pushing current branch."; \
	else \
		echo "Enter commit message, then Ctrl-D:"; \
		msg=$$(cat </dev/tty); \
		if [ -z "$$msg" ]; then echo "Empty commit message, aborting." >&2; exit 1; fi; \
		git commit -m "$$msg"; \
	fi; \
	echo "Pushing to both remotes:"; \
	git remote get-url --push --all origin | sed 's/^/  - /'; \
	git push origin HEAD
