# go-zero 生成風格
GO_ZERO_STYLE := go_zero
GO ?= go
GOFMT ?= gofmt
GOFILES := $(shell find . -name '*.go' -not -path './generate/doc-generate/*')

GO_DOC_DIR  := generate/doc-generate
GO_DOC_BIN  := $(GO_DOC_DIR)/bin/go-doc
API_ENTRY   := ./generate/api/gateway.api
DOC_OUT     := ./docs/openapi

GOCTL ?= goctl
GOCTL_PKG := github.com/zeromicro/go-zero/tools/goctl@latest
GOLANGCI_PKG := github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.12.2

.DEFAULT_GOAL := help

.PHONY: help tools gen-api gen-mock build-go-doc gen-doc test fmt lint lint-fix fix check run \
	deps-up deps-up-smtp deps-down deps-down-v deps-logs deps-ps mongo-index notify-test totp-test member-seed setup-dev run-local

help: ## 顯示可用指令
	@echo "Gateway Makefile"
	@echo ""
	@echo "首次開發："
	@echo "  make tools      安裝 goctl、goimports、golangci-lint（寫入 \$$GOPATH/bin）"
	@echo "  go mod download"
	@echo ""
	@echo "常用："
	@grep -E '^[a-zA-Z0-9_-]+:.*## ' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*## "}; {printf "  make %-14s %s\n", $$1, $$2}'

tools: ## 安裝 goctl、goimports、golangci-lint（需 Go，且 GOPATH/bin 在 PATH）
	@command -v $(GOCTL) >/dev/null 2>&1 || (echo ">> installing goctl" && $(GO) install $(GOCTL_PKG))
	@command -v goimports >/dev/null 2>&1 || (echo ">> installing goimports" && $(GO) install golang.org/x/tools/cmd/goimports@latest)
	@if ! command -v golangci-lint >/dev/null 2>&1 || ! golangci-lint version 2>/dev/null | grep -q 'version 2\.'; then \
		echo ">> installing golangci-lint v2"; \
		$(GO) install $(GOLANGCI_PKG); \
	fi
	@echo "tools OK"
	@echo "  goctl:          $$(goctl --version 2>/dev/null || echo missing)"
	@echo "  golangci-lint:  $$(golangci-lint version 2>/dev/null | head -1 || echo missing)"

gen-api: tools ## 由 .api 生成 handler / logic / types（自訂 handler 模板）
	$(GOCTL) api go -api $(API_ENTRY) -dir . -style $(GO_ZERO_STYLE) -home generate/goctl

gen-mock: ## 依 go:generate 產生 internal/model/*/mock（gomock）
	$(GO) generate ./internal/model/...

build-go-doc: ## 編譯 go-doc（OpenAPI 文件生成器）
	@echo ">> building $(GO_DOC_BIN)"
	@mkdir -p $(GO_DOC_DIR)/bin
	@cd $(GO_DOC_DIR) && $(GO) build -o bin/go-doc ./cmd/go-doc

gen-doc: build-go-doc ## 從 .api 生成 OpenAPI 3.0 YAML
	@mkdir -p $(DOC_OUT)
	$(GO_DOC_BIN) -a $(API_ENTRY) -d $(DOC_OUT) -f gateway -s openapi3.0 -y
	@echo "Generated: $(DOC_OUT)/gateway.yaml"

test: ## 執行測試
	$(GO) test ./...

fmt: ## gofmt + goimports（不含 lint）
	$(GOFMT) -s -w $(GOFILES)
	@command -v goimports >/dev/null 2>&1 && goimports -w . || (echo "goimports not found; run: make tools" && exit 1)

lint: tools ## golangci-lint 靜態檢查
	golangci-lint run ./...

lint-fix: tools ## 自動修正可修的 lint / formatter 問題（見 .golangci.yml）
	golangci-lint run --fix ./...

fix: fmt lint-fix lint ## 格式化 + 自動修 lint + 再檢查（提交前建議）

check: fix test ## 提交 / PR 前完整檢查（fmt、lint、test）

run: ## 啟動 Gateway（etc/gateway.yaml，無需 Docker）
	$(GO) run gateway.go -f etc/gateway.yaml

setup-dev: ## 建立本機 gateway.dev.yaml（自 example，不會被 git 追蹤）
	@test -f etc/gateway.dev.yaml || cp etc/gateway.dev.example.yaml etc/gateway.dev.yaml
	@echo ">> etc/gateway.dev.yaml ready (edit locally; not committed)"

run-dev: setup-dev ## 啟動 Gateway（etc/gateway.dev.yaml，需 make deps-up）
	$(GO) run gateway.go -f etc/gateway.dev.yaml

run-local: run-dev ## 別名：同 run-dev

deps-up: ## 啟動本機 Mongo + Redis（docker compose）
	docker compose up -d mongo redis

deps-up-smtp: ## 啟動 Mongo + Redis + MailHog（本機 SMTP 測試）
	docker compose --profile smtp up -d mongo redis mailhog

deps-down: ## 停止 docker compose 容器（保留 volume）
	docker compose --profile smtp down

deps-down-v: ## 停止並刪除 volume（清空 Mongo/Redis 資料）
	docker compose --profile smtp down -v

deps-logs: ## 查看依賴服務 log
	docker compose --profile smtp logs -f

deps-ps: ## 查看依賴服務狀態
	docker compose --profile smtp ps

mongo-index: ## 建立 notification Mongo 索引（需 Mongo 已啟動）
	$(GO) run ./cmd/mongo-index -f etc/gateway.dev.yaml

notify-test: setup-dev ## 通知測試（METHOD 必填；例: make notify-test METHOD=email-send TO=a@b.com）
	@test -n "$(METHOD)" || (echo "usage: make notify-test METHOD=email-send TO=you@example.com" && \
		echo "       make notify-test METHOD=sms-send PHONE=0912345678" && \
		echo "       make notify-test METHOD=email-send TO=t@e.com MOCK=1" && exit 1)
	$(GO) run ./cmd/notify-test -f etc/gateway.dev.yaml -method "$(METHOD)" \
		$(if $(TO),-to "$(TO)",) $(if $(PHONE),-phone "$(PHONE)",) $(if $(MOCK),-mock,)

totp-test: setup-dev ## 互動式 TOTP 綁定 + 驗證（Google Authenticator；需 Redis）
	$(GO) run ./cmd/totp-test -f etc/gateway.dev.yaml \
		$(if $(TENANT),-tenant "$(TENANT)",) $(if $(UID),-uid "$(UID)",) \
		$(if $(ACCOUNT),-account "$(ACCOUNT)",) $(if $(STEP),-step "$(STEP)",) \
		$(if $(CODE),-code "$(CODE)",)

member-seed: setup-dev ## 建立 dev tenant + member（需 Mongo+Redis）
	$(GO) run ./cmd/member-seed -f etc/gateway.dev.yaml \
		$(if $(TENANT),-tenant "$(TENANT)",) $(if $(EMAIL),-email "$(EMAIL)",)

config-check: ## 驗證 gateway.yaml / gateway.dev.yaml 可載入
	$(GO) test ./internal/config/ -run TestLoadGatewayYAML -v
