REGISTRY_HOST = mxqrregistry.net.telmex.com
REGISTRY      = $(REGISTRY_HOST)/daas/csharp-dao
TAG          ?= dev
CHART         = ./app_chart
RELEASE       = csharp-dao
# Sin default a propósito: este chart no distingue QA/Prod por convención
# fija (a diferencia de k8s_dplymnts_daas), así que forzamos que se pase
# explícito para no desplegar por accidente al namespace equivocado.
NS            ?=

SLN           = cloudservicesDAO.sln
SERVER_PROJ   = server/server.csproj
TEST_PROJ     = tests/DynamicCrud.Tests/DynamicCrud.Tests.csproj

# Cluster de gestión — DONDE se aplica el helm upgrade. Vacío = usa el
# contexto activo de kubectl, que es justo como se termina desplegando al
# cluster equivocado. Pásalo siempre:
#   make helm-deploy NS=daas TAG=1.2.3 MGMT_CONTEXT=mi-contexto
MGMT_CONTEXT ?=
KUBECTL       = kubectl $(if $(MGMT_CONTEXT),--context=$(MGMT_CONTEXT),)
HELM          = helm $(if $(MGMT_CONTEXT),--kube-context=$(MGMT_CONTEXT),)

# Variables de entorno — cada target que las necesita hace ". ./.env" él mismo
# y valida que no estén vacías; no hace falta source antes de make.
# OJO: .env NO sirve para variables de make ($(VAR) se expande antes de correr
# la receta); solo para las que se leen en tiempo de shell ($$VAR).
ENV_FILE = .env
ENV_VARS = REGISTRY_USER REGISTRY_PASS CONNECTION_STRING_MAIN

.PHONY: help restore build test test-grpc test-db run docker-build docker-login docker-push \
	helm-deploy deploy

help:
	@echo ""
	@echo "Uso: make <target> [TAG=x.y.z] [NS=namespace] [MGMT_CONTEXT=ctx]   (lee $(ENV_FILE) automáticamente)"
	@echo ""
	@echo "  Desarrollo local (requiere server/appsettings.secrets.json, ver README):"
	@echo "  restore                 dotnet restore"
	@echo "  build                   dotnet build $(SLN)"
	@echo "  test                    dotnet test $(TEST_PROJ) (todo: BD + gRPC)"
	@echo "  test-db                 Solo las pruebas que pegan directo a la BD"
	@echo "  run                     Corre el servidor localmente (dotnet run)"
	@echo ""
	@echo "  Pruebas de caja negra contra el DAO desplegado (solo consultas, no escriben):"
	@echo "  test-grpc               Requiere port-forward activo. Endpoint por defecto: https://127.0.0.1:8440"
	@echo "                            kubectl port-forward svc/csharp-dao-service 8440:8440 -n <ns>"
	@echo "                            make test-grpc DAO_ENDPOINT=http://127.0.0.1:50051  (puerto sin TLS)"
	@echo ""
	@echo "  Docker:"
	@echo "  docker-build            docker build → tag: $(REGISTRY):\$$(TAG)"
	@echo "  docker-push             docker push (usa tu sesión de docker ya activa para $(REGISTRY_HOST))"
	@echo "  docker-login            Solo si necesitas cambiar de cuenta o en CI — no lo corre docker-push"
	@echo ""
	@echo "  Helm (requiere NS explícito):"
	@echo "  helm-deploy              helm upgrade --install $(RELEASE) $(CHART) -n \$$(NS)"
	@echo "                            inyecta CONNECTION_STRING_MAIN de $(ENV_FILE) como Secret (ConnectionStrings__Main)"
	@echo ""
	@echo "  deploy                   docker-build + docker-push + helm-deploy"
	@echo ""
	@echo "Variables (valor efectivo ahora; se sobreescriben en la línea de make):"
	@echo "  TAG               = $(TAG)"
	@echo "  NS                = $(if $(NS),$(NS),<vacío> → helm-deploy fallará hasta que lo pases)"
	@echo "  MGMT_CONTEXT      = $(if $(MGMT_CONTEXT),$(MGMT_CONTEXT),<vacío> → usa el contexto actual de kubectl)"
	@echo "  RELEASE / CHART   = $(RELEASE) / $(CHART)   (fijos)"
	@echo "  REGISTRY          = $(REGISTRY)   (fijo)"
	@echo ""
	@echo "Variables de $(ENV_FILE) (se leen dentro de la receta, no por línea de make):"
	@[ -f ./$(ENV_FILE) ] && . ./$(ENV_FILE) 2>/dev/null; \
	for v in $(ENV_VARS); do \
		eval "val=\$$$$v"; \
		if [ -n "$$val" ]; then st="definida"; else st="VACÍA"; fi; \
		printf "  %-24s = %s\n" "$$v" "$$st"; \
	done
	@echo ""

# ---------------------------------------------------------
# Desarrollo local
# ---------------------------------------------------------

restore:
	dotnet restore $(SLN)

build:
	dotnet build $(SLN)

# Tests de integración: pegan contra una BD real (ver README, sección
# "Credenciales de base de datos"). No corren en un entorno sin BD accesible.
test:
	dotnet test $(TEST_PROJ)

# Suite de caja negra por gRPC contra el DAO ya desplegado. Solo consultas: no
# ejecuta Create/Update/Delete/Upsert/Bulk*, así que es idempotente sobre el
# entorno destino y se puede correr contra QA sin ensuciar nada.
#
# Requiere un port-forward activo antes de correrla:
#   kubectl port-forward svc/csharp-dao-service 8440:8440 -n <namespace>
#
# Para apuntar a otro endpoint (por ejemplo el puerto sin TLS del pod):
#   make test-grpc DAO_ENDPOINT=http://127.0.0.1:50051
DAO_ENDPOINT ?=
test-grpc:
	$(if $(DAO_ENDPOINT),Dao__GrpcEndpoint=$(DAO_ENDPOINT)) dotnet test $(TEST_PROJ) --filter "suite=grpc"

# Las pruebas que pegan directo a la BD (las originales), excluyendo la suite gRPC.
test-db:
	dotnet test $(TEST_PROJ) --filter "suite!=grpc"

run:
	dotnet run --project $(SERVER_PROJ)

# ---------------------------------------------------------
# Docker
# ---------------------------------------------------------
# .dockerignore excluye appsettings.secrets.json y los certificados locales
# a propósito — la cadena de conexión y los certs de producción se inyectan
# vía Secret de Helm, nunca se hornean en la imagen.
#
# --pull es lo que hace que las bases fijadas en el Dockerfile (mcr.microsoft.com/dotnet)
# traigan sus parches: sin él Docker reutiliza la copia local para siempre.
docker-build:
	docker build -f Dockerfile . \
		--pull \
		-t $(REGISTRY):$(TAG)

# No fuerza login: asume que ya tienes una sesión válida en Docker para
# $(REGISTRY_HOST) (docker login manual, una sola vez). Igual que en
# k8s_dplymnts_daas — reautenticar en cada push es lo que rompe una sesión
# buena si REGISTRY_USER/REGISTRY_PASS de $(ENV_FILE) no coinciden con ella.
docker-push:
	docker push $(REGISTRY):$(TAG)

# Target aparte, solo para cuando de verdad necesites cambiar de cuenta o
# para CI (donde no hay sesión previa). No es prerequisito de docker-push.
docker-login:
	@if [ ! -f "./$(ENV_FILE)" ]; then echo "ERROR: no existe ./$(ENV_FILE) (cópialo de .env.example)"; exit 1; fi
	@. ./$(ENV_FILE); \
	if [ -z "$$REGISTRY_USER" ] || [ -z "$$REGISTRY_PASS" ]; then \
		echo "ERROR: REGISTRY_USER/REGISTRY_PASS vacíos en $(ENV_FILE)"; exit 1; \
	fi; \
	echo "$$REGISTRY_PASS" | docker login $(REGISTRY_HOST) -u "$$REGISTRY_USER" --password-stdin

# ---------------------------------------------------------
# Helm deploy
# ---------------------------------------------------------
# database.connectionStringMain se pasa por --set-string (no queda en
# values.yaml, ni en el historial de `helm history` en texto plano más de lo
# que ya implica cualquier Secret de k8s — revísalo con tu política de RBAC).

helm-deploy:
	@if [ -z "$(NS)" ]; then echo "ERROR: falta NS. make helm-deploy NS=<namespace> TAG=<tag>"; exit 1; fi
	@if [ ! -f "./$(ENV_FILE)" ]; then echo "ERROR: no existe ./$(ENV_FILE) (cópialo de .env.example)"; exit 1; fi
	@. ./$(ENV_FILE); \
	miss=""; for v in $(ENV_VARS); do eval "val=\$$$$v"; [ -z "$$val" ] && miss="$$miss $$v"; done; \
	if [ -n "$$miss" ]; then \
		echo "ERROR: variables vacías en $(ENV_FILE):$$miss"; \
		echo "       helm correría igual y el release quedaría a medias."; \
		exit 1; \
	fi
	@echo "helm upgrade en: $$($(KUBECTL) config current-context) / ns=$(NS)"
	. ./$(ENV_FILE) && $(HELM) upgrade --install $(RELEASE) $(CHART) \
		--namespace $(NS) \
		--set image.tag=$(TAG) \
		--set registryCredentials.username="$$REGISTRY_USER" \
		--set registryCredentials.password="$$REGISTRY_PASS" \
		--set-string database.connectionStringMain="$$CONNECTION_STRING_MAIN"

deploy: docker-build docker-push helm-deploy
