# TsDB2 Makefile
# 时序数据库构建、测试与开发工具

.PHONY: all build test clean run help \
        test-unit test-full test-commit test-dirty test-integrity test-mem \
        test-migrate build-migrate \
        test-demos test-demos-heavy test-all \
        build-analyzer build-migrate-web demo-analyzer fmt lint deps tree

# =============================================================================
# 默认目标
# =============================================================================
all: build

# =============================================================================
# 构建
# =============================================================================
build:
	@echo "=== 构建 TsDB2 ==="
	go build ./...
	@echo "✅ 构建完成"

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

# 运行所有核心测试
test: test-unit test-full test-commit test-dirty test-integrity test-mem

# 单元测试: 并发/事务/迁移往返等回归正确性的主要测试网。
# 之前只跑 demo, 这批单测不在日常流程里 —— 现在并入默认 test。
test-unit:
	@echo ""
	@echo "=========================================="
	@echo "  单元测试 (DB / DB/core / migrate)"
	@echo "=========================================="
	go test ./DB/... ./migrate/ -count=1

# 完整功能测试 (28 项测试)
test-full:
	@echo ""
	@echo "=========================================="
	@echo "  完整功能测试 (28 项)"
	@echo "=========================================="
	cd demo/verify_full && go run main.go

# 自动提交机制测试 (5 场景)
test-commit:
	@echo ""
	@echo "=========================================="
	@echo "  自动提交机制测试 (5 场景)"
	@echo "=========================================="
	cd demo/verify_no_commit && go run main.go

# 脏页阈值性能测试
test-dirty:
	@echo ""
	@echo "=========================================="
	@echo "  脏页阈值性能对比测试"
	@echo "=========================================="
	cd demo/verify_dirty_threshold && go run main.go

# 数据完整性测试
test-integrity:
	@echo ""
	@echo "=========================================="
	@echo "  数据完整性测试"
	@echo "=========================================="
	cd demo/verify_integrity && go run main.go

# 内存使用测试
test-mem:
	@echo ""
	@echo "=========================================="
	@echo "  内存使用测试"
	@echo "=========================================="
	cd demo/verify_mem && go run main.go

# =============================================================================
# 跨库迁移 (VRTX ↔ MySQL ↔ SQLite)
# =============================================================================

# 往返一致性测试 (结构 / 数据 / 索引 / 主键 / 边界值 / 时序表)
test-migrate:
	@echo ""
	@echo "=========================================="
	@echo "  跨库迁移往返测试 (VRTX ↔ SQLite)"
	@echo "=========================================="
	go test ./migrate/ -count=1

# 构建跨库迁移命令行工具
build-migrate:
	@echo "=== 构建 vrtxsql ==="
	go build -o vrtxsql ./cmd/vrtxsql
	@echo "✅ 构建完成: ./vrtxsql"

# 构建跨库迁移的 Web 界面 (和 vrtxsql 同一套 migrate 能力, 只是把 flag 换成表单)
build-migrate-web:
	@echo "=== 构建 vrtxsqlweb ==="
	go build -o vrtxsqlweb ./cmd/vrtxsqlweb
	@echo "✅ 构建完成: ./vrtxsqlweb  (启动后打开 http://127.0.0.1:8099)"

# 构建 Analyzer 可执行文件
#
# analyzer 是独立的 module (自带 go.mod), 所以 `go build ./...` 扫不到它 ——
# 想拿到能直接跑、能挂调试器的二进制, 得进它自己的目录编。
# 加 -gcflags="all=-N -l" 可关掉优化与内联 (断点更稳、变量能看全), 排查疑难时用:
#   cd analyzer && go build -gcflags="all=-N -l" -o analyzer .
build-analyzer:
	@echo "=== 构建 analyzer ==="
	cd analyzer && go build -o analyzer .
	@echo "✅ 构建完成: ./analyzer/analyzer  (启动后打开 http://localhost:8081)"

# =============================================================================
# Demo 程序
# =============================================================================

# demo 清单直接取自磁盘 (含 main.go 的目录), 不在这里手抄一份:
# 手抄的清单一定会漏 —— 新加的 demo 没人想起来往 Makefile 里补一行, 于是它
# 再也没被跑过, 而且"清单看起来是全的"这件事本身还会让人放心地不去检查。
DEMO_DIRS := $(patsubst demo/%/main.go,%,$(wildcard demo/*/main.go))

# 重型 demo: 跑得久或吃资源 (千万行压测 / 极端配置), 不进默认的 test-demos。
# 它们同样必须能跑通, 只是要在需要时显式点名: make test-demos-heavy
# 顺序从轻到重, 先看到多数结果, 最慢的 bench_10m 放最后。
HEAVY_DEMOS := hash_bench stress_small_config verify_stress stress_extreme_config bench_10m

# 单独跑一个 demo: make demo-verify_unique_index
demo-%:
	@echo "===== demo/$* ====="
	cd demo/$* && go run main.go

# 跑一遍全部 demo (排除重型)。
#
# 刻意不在第一个失败处退出: 跑一遍只看到第一个坏掉的 demo, 修完再跑又冒出下一个,
# 全量验证要的是"一次拿到所有坏消息"。日志留在 /tmp, 失败时能直接查。
test-demos:
	@echo ""
	@echo "=========================================="
	@echo "  Demo 全量验证 (共 $(words $(filter-out $(HEAVY_DEMOS),$(DEMO_DIRS))) 个)"
	@echo "=========================================="
	@ok=0; fail=0; \
	for d in $(filter-out $(HEAVY_DEMOS),$(DEMO_DIRS)); do \
		printf "  %-26s" "$$d"; \
		if ( cd demo/$$d && go run main.go ) > /tmp/tsdb2_demo_$$d.log 2>&1; then \
			echo "✅ 通过"; ok=$$((ok+1)); \
		else \
			echo "❌ 失败 (日志: /tmp/tsdb2_demo_$$d.log)"; fail=$$((fail+1)); \
		fi; \
	done; \
	echo ""; \
	echo "  结果: 通过 $$ok, 失败 $$fail"; \
	test $$fail -eq 0

# 重型 demo (单独跑)
test-demos-heavy:
	@echo ""
	@echo "=========================================="
	@echo "  重型 Demo (共 $(words $(HEAVY_DEMOS)) 个)"
	@echo "=========================================="
	@ok=0; fail=0; \
	for d in $(HEAVY_DEMOS); do \
		printf "  %-26s" "$$d"; \
		if ( cd demo/$$d && go run main.go ) > /tmp/tsdb2_demo_$$d.log 2>&1; then \
			echo "✅ 通过"; ok=$$((ok+1)); \
		else \
			echo "❌ 失败 (日志: /tmp/tsdb2_demo_$$d.log)"; fail=$$((fail+1)); \
		fi; \
	done; \
	echo ""; \
	echo "  结果: 通过 $$ok, 失败 $$fail"; \
	test $$fail -eq 0

# 一键全量: 构建 + 迁移往返 + 单元测试 + 全部 demo
test-all: build test-migrate test-unit test-demos
	@echo ""
	@echo "✅ 全量验证完成 (重型 demo 另跑: make test-demos-heavy)"

# 运行 Analyzer (数据库可视化工具)
#
# 用 `go run .` 而不是 `go run main.go`: analyzer 是多文件包 (store/pagemap/
# audit/indexcheck...), 只喂一个文件会报一片 undefined。
demo-analyzer:
	@echo "=== 启动 TsDB2 Analyzer ==="
	cd analyzer && go run .

# =============================================================================
# 开发工具
# =============================================================================

# 运行主程序
run:
	@echo "=== 运行主程序 ==="
	go run main.go

# 代码格式化
fmt:
	@echo "=== 格式化代码 ==="
	go fmt ./...
	@echo "✅ 格式化完成"

# 代码静态检查
lint:
	@echo "=== 代码静态检查 ==="
	go vet ./...
	@echo "✅ 检查完成"

# 依赖管理
deps:
	@echo "=== 整理依赖 ==="
	go mod tidy
	@echo "=== 验证依赖 ==="
	go mod verify
	@echo "✅ 依赖检查完成"

# 显示项目结构
tree:
	@echo "=== TsDB2 项目结构 ==="
	@echo ""
	@echo "TsDB2/"
	@echo "├── DB/              # 数据库核心层"
	@echo "│   ├── core/        # 底层引擎 (页式存储、B+树、WAL)"
	@echo "│   ├── db.go        # DB 层封装"
	@echo "│   ├── table.go     # 泛型表操作"
	@echo "│   ├── query.go     # 查询构建器"
	@echo "│   └── model.go     # 模型解析"
	@echo "├── analyzer/        # 数据库可视化工具"
	@echo "├── demo/            # 测试程序"
	@echo "│   ├── verify_full/       # 完整功能测试"
	@echo "│   ├── verify_no_commit/  # 自动提交测试"
	@echo "│   ├── verify_dirty_threshold/ # 脏页阈值测试"
	@echo "│   ├── verify_integrity/    # 数据完整性测试"
	@echo "│   └── verify_mem/          # 内存使用测试"
	@echo "├── docs/            # 文档"
	@echo "└── Makefile         # 构建脚本"
	@echo ""

# 清理临时文件
clean:
	@echo "=== 清理临时文件 ==="
	@rm -f demo/*/*.db
	@rm -f *.db
	@rm -f demo/*/*.exe
	@rm -f vrtxsql vrtxsql.exe
	@rm -f vrtxsqlweb vrtxsqlweb.exe
	@rm -f analyzer/analyzer analyzer/analyzer.exe
	@rm -f /tmp/tsdb2_demo_*.log
	@echo "✅ 清理完成"

# =============================================================================
# 帮助信息
# =============================================================================
help:
	@echo "╔═══════════════════════════════════════════════════════════╗"
	@echo "║           TsDB2 Makefile 使用说明                       ║"
	@echo "╚═══════════════════════════════════════════════════════════╝"
	@echo ""
	@echo "📦 构建与运行"
	@echo "  make build       - 构建整个项目"
	@echo "  make run         - 运行主程序"
	@echo "  make clean       - 清理临时文件 (.db, .exe)"
	@echo ""
	@echo "🧪 核心测试"
	@echo "  make test        - 运行所有核心测试 (推荐)"
	@echo "  make test-full   - 完整功能测试 (28 项)"
	@echo "  make test-commit - 自动提交机制测试 (5 场景)"
	@echo "  make test-dirty  - 脏页阈值性能对比测试"
	@echo "  make test-integrity - 数据完整性测试"
	@echo "  make test-mem    - 内存使用测试"
	@echo ""
	@echo "🔀 跨库迁移"
	@echo "  make test-migrate  - 迁移往返一致性测试 (VRTX ↔ SQLite)"
	@echo "  make build-migrate - 构建 vrtxsql 命令行工具"
	@echo "  make build-migrate-web - 构建 vrtxsqlweb 网页版迁移工具"
	@echo "  make build-analyzer - 构建 analyzer 可执行文件"
	@echo ""
	@echo "🎨 Demo 程序"
	@echo "  make test-demos    - 跑一遍全部 demo (排除重型, 逐个报通过/失败)"
	@echo "  make test-demos-heavy - 重型 demo (千万行压测 / 极端配置)"
	@echo "  make demo-<name>   - 单独跑一个 demo (如 make demo-verify_unique_index)"
	@echo "  make demo-analyzer - 启动数据库可视化工具"
	@echo ""
	@echo "🛠️  开发工具"
	@echo "  make fmt         - 格式化代码"
	@echo "  make lint        - 代码静态检查 (go vet)"
	@echo "  make deps        - 依赖管理 (tidy + verify)"
	@echo "  make tree        - 显示项目结构"
	@echo ""
	@echo "📖 快速开始"
	@echo "  make build && make test    # 构建并运行所有测试"
	@echo "  make test-all              # 构建 + 迁移往返 + 全部 demo (一键全量)"
	@echo "  make demo-analyzer         # 启动可视化工具"
	@echo ""
	@echo "💡 提示"
	@echo "  - 首次使用建议运行: make test"
	@echo "  - 查看 Analyzer: make demo-analyzer"
	@echo "  - 提交前检查: make fmt && make lint"
	@echo ""
