COMPOSE_SERVICES := mysql redis gateway-service room-service im-service wallet-service user-service activity-service
SERVICE_ALIASES := gs gateway rs room is im ws wallet us user as activity mysql redis gateway-service room-service im-service wallet-service user-service activity-service
SERVICE_TOKEN := $(firstword $(filter $(SERVICE_ALIASES),$(MAKECMDGOALS)))
SERVICE_ID := $(strip $(or $(SERVICE),$(if $(filter gs gateway,$(SERVICE_TOKEN)),gateway-service,$(if $(filter rs room,$(SERVICE_TOKEN)),room-service,$(if $(filter is im,$(SERVICE_TOKEN)),im-service,$(if $(filter ws wallet,$(SERVICE_TOKEN)),wallet-service,$(if $(filter us user,$(SERVICE_TOKEN)),user-service,$(if $(filter as activity,$(SERVICE_TOKEN)),activity-service,$(SERVICE_TOKEN)))))))))

.PHONY: proto test build up rebuild restart stop logs ps addr down up-service compose-up compose-addresses compose-logs compose-down compose-up-service compose-rebuild-service compose-restart-service compose-stop-service compose-logs-service compose-ps-service check-service $(SERVICE_ALIASES)

# `proto` 负责把仓库内的 .proto 重新生成成 Go 代码。
proto:
	protoc \
		-I . \
		--go_out=. \
		--go_opt=paths=source_relative \
		--go-grpc_out=. \
		--go-grpc_opt=paths=source_relative \
		api/proto/user/v1/user.proto \
		api/proto/user/v1/auth.proto \
		api/proto/activity/v1/activity.proto \
		api/proto/room/v1/room.proto \
		api/proto/im/v1/im.proto \
		api/proto/wallet/v1/wallet.proto \
		api/proto/events/room/v1/events.proto

# `test` 统一跑仓库全部测试。
test:
	go test ./...

# `build` 只验证所有命令入口都能编译。
build:
	go build ./...

# `up` 后台拉起本地服务；带 SERVICE 时只启动单个服务。
up:
	@if [ -z "$(SERVICE_ID)" ]; then \
		docker compose up --build -d; \
	else \
		docker compose up -d $(SERVICE_ID); \
	fi
	./scripts/print-compose-addresses.sh

# `rebuild` 重新构建并启动单个本地服务。
rebuild: check-service
	docker compose up -d --build $(SERVICE_ID)
	./scripts/print-compose-addresses.sh

# `restart` 重启单个本地服务。
restart: check-service
	docker compose restart $(SERVICE_ID)

# `stop` 停止单个本地服务。
stop: check-service
	docker compose stop $(SERVICE_ID)

# `logs` 查看日志；带 SERVICE 时只看单个服务。
logs:
	@if [ -z "$(SERVICE_ID)" ]; then \
		docker compose logs -f; \
	else \
		docker compose logs -f --tail=200 $(SERVICE_ID); \
	fi

# `ps` 查看状态；带 SERVICE 时只看单个服务。
ps:
	@if [ -z "$(SERVICE_ID)" ]; then \
		docker compose ps; \
	else \
		docker compose ps $(SERVICE_ID); \
	fi

# `addr` 打印本地和 Docker 内网访问地址。
addr:
	./scripts/print-compose-addresses.sh

# `down` 停止并清理本地 compose 服务。
down:
	docker compose down

# `compose-up` 兼容旧命令，等价于 `up`。
compose-up:
	docker compose up --build -d
	./scripts/print-compose-addresses.sh

# `compose-addresses` 兼容旧命令，等价于 `addr`。
compose-addresses:
	./scripts/print-compose-addresses.sh

# `compose-logs` 兼容旧命令，等价于 `logs`。
compose-logs:
	docker compose logs -f

# `check-service` 校验单服务部署目标的 SERVICE 参数。
check-service:
	@if [ -z "$(SERVICE_ID)" ]; then \
		echo "Service is required. Example: make restart rs"; \
		echo "Aliases: gs/gateway rs/room is/im ws/wallet us/user as/activity mysql redis"; \
		echo "Services: $(COMPOSE_SERVICES)"; \
		exit 1; \
	fi
	@if ! printf '%s\n' $(COMPOSE_SERVICES) | grep -qx "$(SERVICE_ID)"; then \
		echo "Unknown service: $(SERVICE_ID)"; \
		echo "Aliases: gs/gateway rs/room is/im ws/wallet us/user as/activity mysql redis"; \
		echo "Services: $(COMPOSE_SERVICES)"; \
		exit 1; \
	fi

# `up-service` 是 `up SERVICE=...` 的内部实现。
up-service: check-service
	docker compose up -d $(SERVICE_ID)
	./scripts/print-compose-addresses.sh

# `compose-up-service` 兼容旧命令，等价于 `up SERVICE=...`。
compose-up-service: check-service
	docker compose up -d $(SERVICE_ID)
	./scripts/print-compose-addresses.sh

# `compose-rebuild-service` 兼容旧命令，等价于 `rebuild SERVICE=...`。
compose-rebuild-service: check-service
	docker compose up -d --build $(SERVICE_ID)
	./scripts/print-compose-addresses.sh

# `compose-restart-service` 兼容旧命令，等价于 `restart SERVICE=...`。
compose-restart-service: check-service
	docker compose restart $(SERVICE_ID)

# `compose-stop-service` 兼容旧命令，等价于 `stop SERVICE=...`。
compose-stop-service: check-service
	docker compose stop $(SERVICE_ID)

# `compose-logs-service` 兼容旧命令，等价于 `logs SERVICE=...`。
compose-logs-service: check-service
	docker compose logs -f --tail=200 $(SERVICE_ID)

# `compose-ps-service` 兼容旧命令，等价于 `ps SERVICE=...`。
compose-ps-service: check-service
	docker compose ps $(SERVICE_ID)

# 服务别名只用于 `make restart rs` 这类第二参数，不执行动作。
$(SERVICE_ALIASES):
	@:

# `compose-down` 兼容旧命令，等价于 `down`。
compose-down:
	docker compose down
