# Makefile: 適用於 docker-compose 專案，自動取用當前資料夾為專案名

COMPOSE := docker-compose
COMPOSE_FILE := docker-compose.yml
PROJECT_NAME := $(notdir $(CURDIR))  # 依照當前資料夾自動命名

# 資料庫服務名稱與 Volume 名稱
DB_SERVICE_NAME := db # 在 docker-compose.yml 中定義的資料庫服務名稱 (例如：db)
# Docker Compose 預設會為 Volume 加上專案名稱前綴。
# 所以如果你的 Volume 叫 app_postgres_data，且專案名稱是 myproject，
# 那實際的 Volume 名稱會是 myproject_app_postgres_data。
# 若為 standalone 的 docker-compose.yml (不指定 project name)，則為 app_postgres_data。
DB_VOLUME_NAME := $(PROJECT_NAME)_app_postgres_data # 資料庫 Volume 的完整名稱

# 資料庫連線環境變數 (從 docker-compose.yml 的預設值同步過來，以確保備份還原時能正確連線)
DB_USER ?= postgres   # 若未從環境變數指定，預設為 postgres
DB_NAME ?= app_db     # 若未從環境變數指定，預設為 app_db
DB_PASSWORD ?= password # 若未從環境變數指定，預設為 password

# 備份檔案名稱與路徑
BACKUP_DIR := ./db_backups # 備份檔案存放的目錄
BACKUP_FILE := $(BACKUP_DIR)/$(shell date +%Y%m%d_%H%M%S)_$(PROJECT_NAME)_db_backup.sql

# 可選自訂 .env 變數（預設 docker-compose 自動載入 .env 檔）
# ENV_FILE := .env

.PHONY: help up up-fg down build restart logs ps exec clean prune backup-db restore-db

help:
	@echo "🔧 Docker Compose Makefile 指令："
	@echo "  make up             - 啟動所有服務 (背景執行)"
	@echo "  make up-fg          - 前景執行（方便除錯）"
	@echo "  make down           - 停止並移除服務容器"
	@echo "  make build          - 重新建構服務映像檔"
	@echo "  make restart        - 重啟所有服務"
	@echo "  make logs           - 查看服務日誌"
	@echo "  make ps             - 顯示服務狀態"
	@echo "  make exec SERVICE   - 進入指定服務容器的 shell (預設：db)"
	@echo "  make clean          - 清理所有服務容器與相關 Volume (適合砍掉重練)"
	@echo "  make prune          - 清除未使用的 Docker 資源 (映像檔、網路、Volume)"
	@echo ""
	@echo "  make backup-db      - 備份 PostgreSQL 資料庫到 ./db_backups/"
	@echo "  make restore-db FILE - 還原 PostgreSQL 資料庫，FILE 是備份檔的完整路徑"
	@echo "                          範例: make restore-db FILE=./db_backups/20250624_011228_yourproject_db_backup.sql"
	@echo ""
	@echo "⚠️  注意：'restore-db' 會清空目標資料庫後再還原，請謹慎使用。"

up:
	$(COMPOSE) -p $(PROJECT_NAME) -f $(COMPOSE_FILE) up -d

up-fg:
	$(COMPOSE) -p $(PROJECT_NAME) -f $(COMPOSE_FILE) up

down:
	$(COMPOSE) -p $(PROJECT_NAME) -f $(COMPOSE_FILE) down

build:
	$(COMPOSE) -p $(PROJECT_NAME) -f $(COMPOSE_FILE) build

restart:
	$(COMPOSE) -p $(PROJECT_NAME) -f $(COMPOSE_FILE) down
	$(COMPOSE) -p $(PROJECT_NAME) -f $(COMPOSE_FILE) up -d

logs:
	$(COMPOSE) -p $(PROJECT_NAME) -f $(COMPOSE_FILE) logs -f --tail=100

ps:
	$(COMPOSE) -p $(PROJECT_NAME) -f $(COMPOSE_FILE) ps

# 預設進入 db 服務的 shell，也可以指定其他服務
exec:
	$(COMPOSE) -p $(PROJECT_NAME) -f $(COMPOSE_FILE) exec $(or $(SERVICE),$(DB_SERVICE_NAME)) bash

clean:
	$(COMPOSE) -p $(PROJECT_NAME) -f $(COMPOSE_FILE) down -v --remove-orphans

prune:
	docker system prune -af --volumes

# 資料庫備份 (使用 pg_dump)
backup-db:
	@mkdir -p $(BACKUP_DIR) # 確保備份目錄存在
	@echo "✨ 正在備份資料庫 $(DB_NAME) 到 $(BACKUP_FILE)..."
	@docker compose -p $(PROJECT_NAME) -f $(COMPOSE_FILE) exec $(DB_SERVICE_NAME) \
		pg_dump -U "$(DB_USER)" -d "$(DB_NAME)" > "$(BACKUP_FILE)"
	@echo "✅ 資料庫備份完成！"

# 資料庫還原 (使用 psql)
restore-db:
	@if [ -z "$(FILE)" ]; then echo "⚠️ 錯誤: 請提供要還原的備份檔案路徑 (例如: make restore-db FILE=./your_backup.sql)"; exit 1; fi
	@if [ ! -f "$(FILE)" ]; then echo "⚠️ 錯誤: 備份檔案 $(FILE) 不存在！"; exit 1; fi
	@echo "🚨 警告: 正在還原資料庫 $(DB_NAME)。這將清空現有資料！"
	@echo "請輸入 'yes' 確認繼續還原，否則請按 Ctrl+C 取消。"
	@read -p "確認還原？ (yes/no): " CONFIRM_RESTORE; \
	if [ "$$CONFIRM_RESTORE" != "yes" ]; then echo "還原已取消。"; exit 1; fi

	# 停止資料庫服務，確保還原過程不受干擾
	@echo "⏳ 停止資料庫服務中..."
	@docker compose -p $(PROJECT_NAME) -f $(COMPOSE_FILE) stop $(DB_SERVICE_NAME)

	# 移除舊的資料庫 Volume (確保清空資料)
	@echo "🗑️ 移除舊的資料庫 Volume $(DB_VOLUME_NAME)..."
	@docker volume rm $(DB_VOLUME_NAME) || true # 允許 volume 不存在時不報錯

	# 重新啟動資料庫服務，Docker 會自動創建新的空 Volume
	@echo "🚀 重新啟動資料庫服務以創建新的空資料庫..."
	@docker compose -p $(PROJECT_NAME) -f $(COMPOSE_FILE) up -d $(DB_SERVICE_NAME)

	# 等待資料庫服務啟動並準備好接受連線
	@echo "⏱️ 等待資料庫服務啟動並準備好..."
	@for i in `seq 1 10`; do \
		docker compose -p $(PROJECT_NAME) -f $(COMPOSE_FILE) exec $(DB_SERVICE_NAME) pg_isready -d $(DB_NAME) -U $(DB_USER) > /dev/null 2>&1 && break || sleep 5; \
	done
	@docker compose -p $(PROJECT_NAME) -f $(COMPOSE_FILE) exec $(DB_SERVICE_NAME) pg_isready -d $(DB_NAME) -U $(DB_USER) || { echo "❌ 資料庫啟動失敗或無法連線！"; exit 1; }

	# 匯入備份檔案
	@echo "✨ 正在將備份檔案 $(FILE) 匯入資料庫 $(DB_NAME)..."
	@docker compose -p $(PROJECT_NAME) -f $(COMPOSE_FILE) exec -T $(DB_SERVICE_NAME) \
		psql -U "$(DB_USER)" -d "$(DB_NAME)" < "$(FILE)"
	@echo "✅ 資料庫還原完成！"