# Pipeline Database - Makefile
# ===================================

# 项目信息
PROJECT_NAME := pipelinedb
VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")

# Go 工具
GOCMD := go
GOTEST := $(GOCMD) test
GOMOD := $(GOCMD) mod
GOFMT := gofmt
GOVET := $(GOCMD) vet
GOLINT := golangci-lint

# 目录定义
COVERAGE_DIR := coverage
EXAMPLES_DIR := examples

# 默认目标
.PHONY: all
all: deps fmt vet test

# ==================== 依赖管理 ====================

.PHONY: deps
deps: ## 下载依赖
	@echo "📦 下载依赖..."
	$(GOMOD) download
	$(GOMOD) tidy

.PHONY: deps-update
deps-update: ## 更新依赖
	@echo "🔄 更新依赖..."
	$(GOMOD) get -u ./...
	$(GOMOD) tidy

.PHONY: deps-verify
deps-verify: ## 验证依赖
	@echo "✅ 验证依赖..."
	$(GOMOD) verify

# ==================== 代码格式化和检查 ====================

.PHONY: fmt
fmt: ## 格式化代码
	@echo "🎨 格式化代码..."
	$(GOFMT) -s -w .
	$(GOCMD) mod tidy

.PHONY: fmt-check
fmt-check: ## 检查代码格式
	@echo "🔍 检查代码格式..."
	@if [ -n "$$($(GOFMT) -s -l .)" ]; then \
		echo "❌ 以下文件需要格式化:"; \
		$(GOFMT) -s -l .; \
		exit 1; \
	fi
	@echo "✅ 代码格式正确"

.PHONY: vet
vet: ## 静态代码分析
	@echo "🔍 静态代码分析..."
	$(GOVET) ./...

.PHONY: lint
lint: ## 代码质量检查
	@echo "🔍 代码质量检查..."
	@if command -v $(GOLINT) >/dev/null 2>&1; then \
		$(GOLINT) run --timeout=5m; \
	else \
		echo "⚠️  golangci-lint 未安装，跳过 lint 检查"; \
		echo "安装命令: go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest"; \
	fi

.PHONY: lint-install
lint-install: ## 安装代码质量检查工具
	@echo "📥 安装 golangci-lint..."
	go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest


# ==================== 测试 ====================

.PHONY: test
test: ## 运行测试
	@echo "🧪 运行测试..."
	$(GOTEST) -v -race ./...

.PHONY: test-short
test-short: ## 运行快速测试
	@echo "⚡ 运行快速测试..."
	$(GOTEST) -short -v ./...

.PHONY: test-coverage
test-coverage: ## 生成测试覆盖率报告
	@echo "📊 生成测试覆盖率报告..."
	@mkdir -p $(COVERAGE_DIR)
	$(GOCMD) tool cover -html=$(COVERAGE_DIR)/coverage.out -o $(COVERAGE_DIR)/coverage.html
	$(GOCMD) tool cover -func=$(COVERAGE_DIR)/coverage.out | grep total

.PHONY: test-coverage-ci
test-coverage-ci: ## CI环境的覆盖率测试
	@echo "📊 CI 环境测试覆盖率..."
	$(GOTEST) -v -coverprofile=coverage.out ./...
	@COVERAGE=$$(go tool cover -func=coverage.out | grep total | awk '{print $$3}' | sed 's/%//'); \
	echo "测试覆盖率: $${COVERAGE}%"; \
	if [ "$$(echo "$$COVERAGE < 70" | bc -l)" -eq 1 ]; then \
		echo "❌ 测试覆盖率低于 70%"; \
		exit 1; \
	fi; \
	echo "✅ 测试覆盖率达标"

# ==================== 基准测试 ====================

.PHONY: bench
bench: ## 运行基准测试
	@echo "⚡ 运行基准测试..."
	$(GOTEST) -bench=. -benchmem -run=^$$ ./...

.PHONY: bench-cpu
bench-cpu: ## CPU性能分析
	@echo "🔥 CPU 性能分析..."
	@mkdir -p $(COVERAGE_DIR)
	$(GOTEST) -bench=BenchmarkConcurrentAcceptData -cpuprofile=$(COVERAGE_DIR)/cpu.prof -run=^$$ ./...
	$(GOCMD) tool pprof -text $(COVERAGE_DIR)/cpu.prof | head -20

.PHONY: bench-mem
bench-mem: ## 内存性能分析
	@echo "💾 内存性能分析..."
	@mkdir -p $(COVERAGE_DIR)
	$(GOTEST) -bench=BenchmarkConcurrentAcceptData -memprofile=$(COVERAGE_DIR)/mem.prof -run=^$$ ./...
	$(GOCMD) tool pprof -text $(COVERAGE_DIR)/mem.prof | head -20

.PHONY: bench-concurrent
bench-concurrent: ## 并发基准测试
	@echo "🚀 并发基准测试..."
	$(GOTEST) -bench=BenchmarkConcurrent -benchmem -benchtime=2s -run=^$$ ./...

.PHONY: bench-all
bench-all: ## 完整基准测试套件
	@echo "📊 完整基准测试套件..."
	@echo "=== 核心功能基准测试 ==="
	$(GOTEST) -bench=BenchmarkPipelineDB -benchmem -benchtime=1s -run=^$$ ./...
	@echo "=== 并发性能基准测试 ==="
	$(GOTEST) -bench=BenchmarkConcurrent -benchmem -benchtime=1s -run=^$$ ./...
	@echo "=== 存储引擎基准测试 ==="
	$(GOTEST) -bench=BenchmarkStorage -benchmem -benchtime=1s -run=^$$ ./...
	@echo "=== 缓存系统基准测试 ==="
	$(GOTEST) -bench=BenchmarkCache -benchmem -benchtime=1s -run=^$$ ./...

# ==================== 示例运行 ====================

.PHONY: run-basic
run-basic: ## 运行基础使用示例
	@echo "🎯 运行基础使用示例..."
	@cd $(EXAMPLES_DIR)/basic-usage && GOWORK=off $(GOCMD) run main.go

.PHONY: run-group
run-group: ## 运行组管理示例
	@echo "🎯 运行组管理示例..."
	@cd $(EXAMPLES_DIR)/group-management && GOWORK=off $(GOCMD) run main.go

.PHONY: run-handler
run-handler: ## 运行处理器示例
	@echo "🎯 运行处理器示例..."
	@cd $(EXAMPLES_DIR)/external-handler && GOWORK=off $(GOCMD) run main.go

.PHONY: run-auto
run-auto: ## 运行自动处理示例
	@echo "🚀 运行自动处理示例..."
	@cd $(EXAMPLES_DIR)/auto-processing && GOWORK=off $(GOCMD) run main.go

# ==================== 安全和质量 ====================

.PHONY: security
security: ## 安全扫描
	@echo "🔒 安全扫描..."
	@if command -v gosec >/dev/null 2>&1; then \
		gosec ./...; \
	else \
		echo "⚠️  gosec 未安装，跳过安全扫描"; \
		echo "安装命令: go install github.com/securego/gosec/v2/cmd/gosec@latest"; \
	fi

.PHONY: security-install
security-install: ## 安装安全扫描工具
	@echo "📥 安装 gosec..."
	go install github.com/securego/gosec/v2/cmd/gosec@latest

.PHONY: complexity
complexity: ## 检查代码复杂度
	@echo "🔍 检查代码复杂度..."
	@if command -v gocyclo >/dev/null 2>&1; then \
		gocyclo -over 15 .; \
	else \
		echo "⚠️  gocyclo 未安装，跳过复杂度检查"; \
		echo "安装命令: go install github.com/fzipp/gocyclo/cmd/gocyclo@latest"; \
	fi

.PHONY: yaml-check
yaml-check: ## 检查 YAML 文件语法
	@echo "📋 检查 YAML 文件语法..."
	@if command -v yamllint >/dev/null 2>&1; then \
		yamllint .gitea/workflows/*.yml || true; \
	else \
		echo "⚠️  yamllint 未安装，跳过 YAML 检查"; \
		echo "安装命令: make yamllint-install"; \
	fi

.PHONY: yamllint-install
yamllint-install: ## 安装 YAML 语法检查工具
	@echo "📥 安装 yamllint..."
	@if command -v brew >/dev/null 2>&1; then \
		echo "使用 Homebrew 安装 yamllint..."; \
		brew install yamllint; \
	elif command -v apt-get >/dev/null 2>&1; then \
		echo "使用 apt-get 安装 yamllint..."; \
		sudo apt-get update && sudo apt-get install -y yamllint; \
	elif command -v yum >/dev/null 2>&1; then \
		echo "使用 yum 安装 yamllint..."; \
		sudo yum install -y yamllint; \
	elif command -v dnf >/dev/null 2>&1; then \
		echo "使用 dnf 安装 yamllint..."; \
		sudo dnf install -y yamllint; \
	elif command -v pipx >/dev/null 2>&1; then \
		echo "使用 pipx 安装 yamllint..."; \
		pipx install yamllint; \
	elif command -v pip3 >/dev/null 2>&1; then \
		echo "使用 pip3 安装 yamllint (用户模式)..."; \
		pip3 install --user --break-system-packages yamllint 2>/dev/null || pip3 install --user yamllint; \
	elif command -v pip >/dev/null 2>&1; then \
		echo "使用 pip 安装 yamllint (用户模式)..."; \
		pip install --user --break-system-packages yamllint 2>/dev/null || pip install --user yamllint; \
	else \
		echo "❌ 无法找到包管理器，请手动安装 yamllint"; \
		echo "macOS: brew install yamllint"; \
		echo "Ubuntu/Debian: sudo apt-get install yamllint"; \
		echo "CentOS/RHEL: sudo yum install yamllint"; \
		echo "Python: pipx install yamllint"; \
		exit 1; \
	fi

.PHONY: tools-install
tools-install: lint-install security-install yamllint-install ## 安装所有开发工具
	@echo "📥 安装开发工具..."
	go install github.com/fzipp/gocyclo/cmd/gocyclo@latest
	go install honnef.co/go/tools/cmd/staticcheck@latest
	go install github.com/mibk/dupl@latest

# ==================== CI/CD 相关 ====================

.PHONY: ci
ci: deps fmt-check vet yaml-check test-coverage-ci ## CI 流水线
	@echo "🤖 CI 流水线完成"

.PHONY: pre-commit
pre-commit: fmt vet test ## 提交前检查
	@echo "✅ 提交前检查完成"

# ==================== 发布相关 ====================

.PHONY: release
release: ci ## 创建发布标签
	@echo "🏷️  准备创建发布标签..."
	@if [ "$(VERSION)" = "dev" ]; then \
		echo "❌ 请先创建 Git 标签，例如: git tag v1.0.0"; \
		exit 1; \
	fi
	@echo "📋 当前版本: $(VERSION)"
	@echo "📊 运行最终检查..."
	@git status --porcelain | grep -q . && echo "❌ 工作目录不干净，请先提交所有更改" && exit 1 || true
	@echo "✅ 工作目录干净"
	@echo "🎉 发布标签 $(VERSION) 已准备就绪"
	@echo ""
	@echo "📦 发布信息:"
	@echo "  版本: $(VERSION)"
	@echo "  提交: $$(git rev-parse HEAD)"
	@echo "  分支: $$(git branch --show-current)"
	@echo "  时间: $$(date)"
	@echo ""
	@echo "🚀 要推送标签到远程仓库，请运行:"
	@echo "  git push origin $(VERSION)"

.PHONY: tag
tag: ## 创建新的版本标签
	@echo "🏷️  创建新版本标签..."
	@read -p "请输入版本号 (例如 v1.0.0): " version; \
	if [ -z "$$version" ]; then \
		echo "❌ 版本号不能为空"; \
		exit 1; \
	fi; \
	echo "📋 创建标签: $$version"; \
	git tag -a "$$version" -m "Release $$version"; \
	echo "✅ 标签 $$version 已创建"; \
	echo "🚀 要推送标签，请运行: git push origin $$version"

# ==================== 清理 ====================

.PHONY: clean
clean: ## 清理临时文件
	@echo "🧹 清理临时文件..."
	@rm -rf $(COVERAGE_DIR)
	@rm -f coverage.out *.prof
	@find . -name "*.db" -type f -delete 2>/dev/null || true
	@find . -name "*.log" -type f -delete 2>/dev/null || true

# ==================== 开发辅助 ====================

.PHONY: dev-setup
dev-setup: deps tools-install ## 开发环境设置
	@echo "🛠️  开发环境设置完成"

.PHONY: help
help: ## 显示帮助信息
	@echo "Pipeline Database - Makefile 帮助"
	@echo "======================================"
	@echo ""
	@echo "可用命令:"
	@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "  \033[36m%-20s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
	@echo ""
	@echo "常用命令组合:"
	@echo "  make dev-setup     # 初始化开发环境"
	@echo "  make pre-commit    # 提交前检查"
	@echo "  make ci            # CI 流水线"
	@echo "  make tag           # 创建版本标签"
	@echo "  make release       # 发布检查"

# 默认显示帮助
.DEFAULT_GOAL := help
