# 巡樓 monorepo Makefile
# 兩種模式：
#   dev  - 本機開發（docker 起 Mongo/Redis，go run / vite dev）
#   prod - 建置產物（前端 dist + linux Go binary），並可部署成 systemd 服務 + nginx
#
# 常用：
#   make dev-infra         # 起本機 Mongo/Redis
#   make dev-backend       # 跑 gateway (:8890)
#   make dev-frontend      # 跑前端 (:5173，proxy 到 :8890)
#   make build             # 產出 frontend/dist + backend/bin/{gateway,worker}
#   sudo make install      # 部署到目標主機（見 infra/README.md）

SHELL := /bin/bash

# --- 路徑 ---
BACKEND_DIR  := backend
FRONTEND_DIR := frontend
INFRA_DIR    := infra
BIN_DIR      := $(BACKEND_DIR)/bin

# --- 部署目標（install 用）---
DEPLOY_ROOT  := /opt/haixun
WEB_ROOT     := /var/www/haixun

# --- 交叉編譯目標（在 mac 上 build 給 linux 主機）---
GOOS         ?= linux
GOARCH       ?= amd64

# --- docker compose ---
COMPOSE := docker compose -f $(INFRA_DIR)/docker-compose.yml --env-file $(INFRA_DIR)/.env

# --- dev 用 worker secret（對應 etc/gateway.yaml 的 InternalWorker.Secret）---
DEV_WORKER_SECRET := haixun-dev-worker-secret
DEV_BACKEND_URL   := http://127.0.0.1:8890

.DEFAULT_GOAL := help

.PHONY: help
help: ## 顯示可用指令
	@grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) \
		| awk 'BEGIN {FS = ":.*?## "}; {printf "  \033[36m%-20s\033[0m %s\n", $$1, $$2}'

# ============================================================
# DEV
# ============================================================

$(INFRA_DIR)/.env:
	@test -f $(INFRA_DIR)/.env || (cp $(INFRA_DIR)/.env.example $(INFRA_DIR)/.env && echo "已從 .env.example 建立 $(INFRA_DIR)/.env，請視需要修改密碼")

.PHONY: dev-infra
dev-infra: $(INFRA_DIR)/.env ## [dev] 起本機 Mongo + Redis (docker)
	$(COMPOSE) up -d
	$(COMPOSE) ps

.PHONY: dev-infra-down
dev-infra-down: ## [dev] 停掉本機 Mongo + Redis
	$(COMPOSE) down

.PHONY: dev-backend
dev-backend: ## [dev] 跑 gateway API (:8890)
	cd $(BACKEND_DIR) && go run . -f etc/gateway.yaml

.PHONY: dev-worker
dev-worker: ## [dev] 跑 Go job worker (:8891)
	cd $(BACKEND_DIR) && go run ./cmd/worker -f etc/gateway.worker.yaml

.PHONY: dev-node-worker
dev-node-worker: ## [dev] 跑 Node playwright worker (style-8d)
	cd $(BACKEND_DIR)/worker && npm install && \
		HAIXUN_WORKER_SECRET=$(DEV_WORKER_SECRET) HAIXUN_BACKEND_URL=$(DEV_BACKEND_URL) npm run style-8d

.PHONY: dev-frontend
dev-frontend: ## [dev] 跑前端 dev server (:5173)
	cd $(FRONTEND_DIR) && npm install && npm run dev

.PHONY: dev-init
dev-init: ## [dev] 初始化 DB（索引/權限）並建立 admin 帳號（可用 INIT_ADMIN_EMAIL / INIT_ADMIN_PASSWORD 覆寫）
	cd $(BACKEND_DIR) && go run ./cmd/tool init -f etc/gateway.yaml

.PHONY: dev
dev: ## [dev] 顯示本機開發要開的終端
	@echo "本機開發請分開幾個終端執行："
	@echo "  1) make dev-infra        # Mongo/Redis"
	@echo "  2) make dev-backend      # gateway :8890"
	@echo "  3) make dev-worker       # go worker（可選）"
	@echo "  4) make dev-node-worker  # node worker（需 style-8d 時）"
	@echo "  5) make dev-frontend     # 前端 :5173"

# ============================================================
# 安裝依賴（新機器 clone 後執行一次）
# ============================================================

.PHONY: bootstrap-sys
bootstrap-sys: ## [需 sudo] 安裝系統依賴（Go, Node.js, Docker, Nginx）— Ubuntu 專用
	@echo "=== 安裝系統套件: nginx, curl, gnupg ==="
	sudo apt-get update -qq
	sudo apt-get install -y -qq nginx curl gnupg ca-certificates
	@echo ""
	@echo "=== 安裝 Go 1.22+ ==="
	@GO_VER=$$(curl -sL https://go.dev/VERSION?m=text 2>/dev/null | head -1 || echo "go1.22"); \
		echo "下載 $$GO_VER.linux-amd64.tar.gz"; \
		curl -sL "https://go.dev/dl/$$GO_VER.linux-amd64.tar.gz" -o /tmp/go.tar.gz && \
		sudo rm -rf /usr/local/go && \
		sudo tar -C /usr/local -xzf /tmp/go.tar.gz && \
		rm /tmp/go.tar.gz; \
		echo 'export PATH=/usr/local/go/bin:$$PATH' | sudo tee /etc/profile.d/go.sh
	@echo ""
	@echo "=== 安裝 Node.js LTS ==="
	curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
	sudo apt-get install -y -qq nodejs
	@echo ""
	@echo "=== 安裝 Docker Engine + Compose ==="
	curl -fsSL https://get.docker.com | sudo sh
	sudo usermod -aG docker $(USER) 2>/dev/null || true
	@echo ""
	@echo "=== 安裝 Nginx ==="
	sudo apt-get install -y -qq nginx
	@echo ""
	@echo "✓ 系統依賴安裝完成。"
	@echo "  登出再登入後，Go/Node/Docker 即可使用（group 變更生效）。"
	@echo "  接著執行 make bootstrap 安裝專案層依賴。"
	@echo ""

.PHONY: bootstrap
bootstrap: ## 安裝專案層依賴（Go modules + npm + Playwright），需先執行 make bootstrap-sys
	@echo "=== [1/4] Go modules ==="
	cd $(BACKEND_DIR) && go mod tidy
	@echo ""
	@echo "=== [2/4] 前端 npm ==="
	cd $(FRONTEND_DIR) && npm install
	@echo ""
	@echo "=== [3/4] Node worker npm ==="
	cd $(BACKEND_DIR)/worker && npm install
	@echo ""
	@echo "=== [4/4] Playwright 瀏覽器（chromium）+ 系統依賴 ==="
	cd $(BACKEND_DIR)/worker && sudo npx playwright install --with-deps chromium
	@echo ""
	@echo "✓ 全裝完成。後續步驟："
	@echo "  1) make dev-infra        # 起 Mongo/Redis (Docker)"
	@echo "  2) make dev-init         # 初始化 DB + 建立 admin"
	@echo "  3) make dev-backend      # 啟動 gateway (:8890)"
	@echo "  4) sudo make install     # 正式部署（含 systemd + nginx）"

# ============================================================
# BUILD (prod 產物)
# ============================================================

.PHONY: build
build: build-frontend build-backend ## [prod] 建置前端 dist 與 Go binary

.PHONY: build-frontend
build-frontend: ## [prod] 前端靜態建置 (tsc + vite) -> frontend/dist
	cd $(FRONTEND_DIR) && npm ci && npm run build

.PHONY: build-backend
build-backend: ## [prod] 交叉編譯 gateway + worker -> backend/bin (linux)
	cd $(BACKEND_DIR) && CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(GOARCH) \
		go build -trimpath -ldflags "-s -w" -o bin/gateway .
	cd $(BACKEND_DIR) && CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(GOARCH) \
		go build -trimpath -ldflags "-s -w" -o bin/worker ./cmd/worker
	cd $(BACKEND_DIR) && CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(GOARCH) \
		go build -trimpath -ldflags "-s -w" -o bin/tool ./cmd/tool
	@echo "binary 已輸出到 $(BIN_DIR)/（gateway / worker / tool）"

# ============================================================
# PROD (部署)
# ============================================================

.PHONY: prod-infra
prod-infra: $(INFRA_DIR)/.env ## [prod] 起 Mongo + Redis (docker，背景)
	$(COMPOSE) up -d

.PHONY: prod-infra-down
prod-infra-down: ## [prod] 停掉 Mongo + Redis
	$(COMPOSE) down

.PHONY: prod-init
prod-init: ## [prod] 目標主機初始化 DB + 建立 admin（讀 /opt/haixun/etc/haixun.env；可加 INIT_ADMIN_EMAIL/PASSWORD）
	@test -x $(DEPLOY_ROOT)/bin/tool || (echo "缺少 $(DEPLOY_ROOT)/bin/tool，請先 make install" && exit 1)
	set -a; . $(DEPLOY_ROOT)/etc/haixun.env; set +a; \
		$(DEPLOY_ROOT)/bin/tool init -f $(DEPLOY_ROOT)/etc/gateway.prod.yaml

.PHONY: install
install: ## [prod] 安裝 binary/前端/設定/systemd/nginx（需 root，在目標主機執行）
	@test -f $(BIN_DIR)/gateway || (echo "缺少 $(BIN_DIR)/gateway，請先在能 build 的機器執行 make build" && exit 1)
	@test -d $(FRONTEND_DIR)/dist || (echo "缺少 $(FRONTEND_DIR)/dist，請先 make build-frontend" && exit 1)
	id haixun >/dev/null 2>&1 || useradd --system --home $(DEPLOY_ROOT) --shell /usr/sbin/nologin haixun
	install -d $(DEPLOY_ROOT)/bin $(DEPLOY_ROOT)/etc $(DEPLOY_ROOT)/node-worker $(WEB_ROOT)
	install -m 0755 $(BIN_DIR)/gateway $(DEPLOY_ROOT)/bin/gateway
	install -m 0755 $(BIN_DIR)/worker $(DEPLOY_ROOT)/bin/worker
	install -m 0755 $(BIN_DIR)/tool $(DEPLOY_ROOT)/bin/tool
	install -m 0644 $(BACKEND_DIR)/etc/gateway.prod.yaml $(DEPLOY_ROOT)/etc/gateway.prod.yaml
	install -m 0644 $(BACKEND_DIR)/etc/gateway.worker.prod.yaml $(DEPLOY_ROOT)/etc/gateway.worker.prod.yaml
	rm -rf $(WEB_ROOT)/* && cp -r $(FRONTEND_DIR)/dist/* $(WEB_ROOT)/
	cp -r $(BACKEND_DIR)/worker/* $(DEPLOY_ROOT)/node-worker/
	cd $(DEPLOY_ROOT)/node-worker && npm ci && npx playwright install --with-deps chromium
	install -m 0644 $(INFRA_DIR)/systemd/haixun-gateway.service /etc/systemd/system/haixun-gateway.service
	install -m 0644 $(INFRA_DIR)/systemd/haixun-worker.service /etc/systemd/system/haixun-worker.service
	install -m 0644 $(INFRA_DIR)/systemd/haixun-node-worker.service /etc/systemd/system/haixun-node-worker.service
	install -m 0644 $(INFRA_DIR)/nginx/haixun.conf /etc/nginx/conf.d/haixun.conf
	chown -R haixun:haixun $(DEPLOY_ROOT) $(WEB_ROOT)
	@echo "----"
	@echo "接著（只做一次）建立 secret 檔："
	@echo "  cp $(INFRA_DIR)/etc/haixun.env.example $(DEPLOY_ROOT)/etc/haixun.env && chmod 600 $(DEPLOY_ROOT)/etc/haixun.env && sudoedit $(DEPLOY_ROOT)/etc/haixun.env"
	@echo "再啟用服務："
	@echo "  systemctl daemon-reload && systemctl enable --now haixun-gateway haixun-worker haixun-node-worker"
	@echo "  nginx -t && systemctl reload nginx"

# ============================================================
# 驗證 / 維護
# ============================================================

.PHONY: tidy
tidy: ## go mod tidy
	cd $(BACKEND_DIR) && go mod tidy

.PHONY: fmt
fmt: ## gofmt 後端
	cd $(BACKEND_DIR) && gofmt -w .

.PHONY: test
test: ## 跑後端測試
	cd $(BACKEND_DIR) && go test ./...

.PHONY: verify
verify: ## 後端 build/test + 前端 build + compose 語法
	cd $(BACKEND_DIR) && go build ./... && go test ./...
	cd $(FRONTEND_DIR) && npm ci && npm run build
	$(COMPOSE) config >/dev/null && echo "docker compose config OK"
