# Claude Mnemonic Makefile

VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
# Pass version to both main package and hooks package
LDFLAGS := -ldflags "-X main.Version=$(VERSION) -X github.com/lukaszraczylo/claude-mnemonic/pkg/hooks.Version=$(VERSION) -s -w" -buildvcs=false
BUILD_DIR := bin
PLUGIN_DIR := plugin
STABLE_BIN := $(HOME)/.claude-mnemonic/bin

# Go settings
GOOS ?= $(shell go env GOOS)
GOARCH ?= $(shell go env GOARCH)

# CGO settings for SQLite FTS5 support
export CGO_ENABLED=1
BUILD_TAGS := -tags "fts5"

.PHONY: all build clean test install lint hooks worker mcp stop-worker start-worker restart-worker dashboard website dev-website setup-libs update-version

all: build

# Download ONNX runtime libraries (all platforms for local dev, skips if present)
setup-libs:
	@./scripts/download-onnx-libs.sh all

# Download ONNX models from Hugging Face (for local dev, skips if present)
setup-models:
	@./scripts/download-models.sh

# Update version in committed plugin metadata
update-version:
	@if [ -f .claude-plugin/plugin.json ]; then \
		sed 's/"version": "[^"]*"/"version": "$(VERSION)"/' .claude-plugin/plugin.json > .claude-plugin/plugin.json.tmp && mv .claude-plugin/plugin.json.tmp .claude-plugin/plugin.json; \
		echo "Updated .claude-plugin/plugin.json to version $(VERSION)"; \
	fi
	@if [ -f marketplace.json ]; then \
		sed 's/"version": "[^"]*"/"version": "$(VERSION)"/' marketplace.json > marketplace.json.tmp && mv marketplace.json.tmp marketplace.json; \
		echo "Updated marketplace.json version fields to $(VERSION)"; \
	fi

# Build all binaries
build: setup-libs update-version dashboard worker hooks mcp

# Build Vue dashboard
dashboard:
	@echo "Building Vue dashboard..."
	@sed 's/{{ .Version }}/$(VERSION)/g' ui/package.json.tpl > ui/package.json
	@cd ui && npm install --silent && npm run build
	@rm -rf internal/worker/static
	@mkdir -p internal/worker/static
	@touch internal/worker/static/placeholder.html
	@cp -r ui/dist/* internal/worker/static/

# Build worker service
worker:
	@echo "Building worker..."
	@mkdir -p $(BUILD_DIR)
	go build $(BUILD_TAGS) $(LDFLAGS) -o $(BUILD_DIR)/worker ./cmd/worker

# Build all hooks
hooks:
	@echo "Building hooks..."
	@mkdir -p $(BUILD_DIR)/hooks
	go build $(BUILD_TAGS) $(LDFLAGS) -o $(BUILD_DIR)/hooks/session-start ./cmd/hooks/session-start
	go build $(BUILD_TAGS) $(LDFLAGS) -o $(BUILD_DIR)/hooks/user-prompt ./cmd/hooks/user-prompt
	go build $(BUILD_TAGS) $(LDFLAGS) -o $(BUILD_DIR)/hooks/post-tool-use ./cmd/hooks/post-tool-use
	go build $(BUILD_TAGS) $(LDFLAGS) -o $(BUILD_DIR)/hooks/subagent-stop ./cmd/hooks/subagent-stop
	go build $(BUILD_TAGS) $(LDFLAGS) -o $(BUILD_DIR)/hooks/stop ./cmd/hooks/stop
	go build $(BUILD_TAGS) $(LDFLAGS) -o $(BUILD_DIR)/hooks/statusline ./cmd/hooks/statusline

# Build MCP server
mcp:
	@echo "Building MCP server..."
	@mkdir -p $(BUILD_DIR)
	go build $(BUILD_TAGS) $(LDFLAGS) -o $(BUILD_DIR)/mcp-server ./cmd/mcp

# Build for all platforms
build-all: build-linux build-darwin build-windows

build-linux:
	@echo "Building for Linux..."
	@mkdir -p $(BUILD_DIR)/linux-amd64/hooks
	GOOS=linux GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/linux-amd64/worker ./cmd/worker
	GOOS=linux GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/linux-amd64/mcp-server ./cmd/mcp
	GOOS=linux GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/linux-amd64/hooks/session-start ./cmd/hooks/session-start
	GOOS=linux GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/linux-amd64/hooks/user-prompt ./cmd/hooks/user-prompt
	GOOS=linux GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/linux-amd64/hooks/post-tool-use ./cmd/hooks/post-tool-use
	GOOS=linux GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/linux-amd64/hooks/subagent-stop ./cmd/hooks/subagent-stop
	GOOS=linux GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/linux-amd64/hooks/stop ./cmd/hooks/stop
	GOOS=linux GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/linux-amd64/hooks/statusline ./cmd/hooks/statusline

build-darwin:
	@echo "Building for macOS..."
	@mkdir -p $(BUILD_DIR)/darwin-amd64/hooks $(BUILD_DIR)/darwin-arm64/hooks
	GOOS=darwin GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/darwin-amd64/worker ./cmd/worker
	GOOS=darwin GOARCH=arm64 go build $(LDFLAGS) -o $(BUILD_DIR)/darwin-arm64/worker ./cmd/worker
	GOOS=darwin GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/darwin-amd64/mcp-server ./cmd/mcp
	GOOS=darwin GOARCH=arm64 go build $(LDFLAGS) -o $(BUILD_DIR)/darwin-arm64/mcp-server ./cmd/mcp
	GOOS=darwin GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/darwin-amd64/hooks/session-start ./cmd/hooks/session-start
	GOOS=darwin GOARCH=arm64 go build $(LDFLAGS) -o $(BUILD_DIR)/darwin-arm64/hooks/session-start ./cmd/hooks/session-start
	GOOS=darwin GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/darwin-amd64/hooks/user-prompt ./cmd/hooks/user-prompt
	GOOS=darwin GOARCH=arm64 go build $(LDFLAGS) -o $(BUILD_DIR)/darwin-arm64/hooks/user-prompt ./cmd/hooks/user-prompt
	GOOS=darwin GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/darwin-amd64/hooks/post-tool-use ./cmd/hooks/post-tool-use
	GOOS=darwin GOARCH=arm64 go build $(LDFLAGS) -o $(BUILD_DIR)/darwin-arm64/hooks/post-tool-use ./cmd/hooks/post-tool-use
	GOOS=darwin GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/darwin-amd64/hooks/subagent-stop ./cmd/hooks/subagent-stop
	GOOS=darwin GOARCH=arm64 go build $(LDFLAGS) -o $(BUILD_DIR)/darwin-arm64/hooks/subagent-stop ./cmd/hooks/subagent-stop
	GOOS=darwin GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/darwin-amd64/hooks/stop ./cmd/hooks/stop
	GOOS=darwin GOARCH=arm64 go build $(LDFLAGS) -o $(BUILD_DIR)/darwin-arm64/hooks/stop ./cmd/hooks/stop
	GOOS=darwin GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/darwin-amd64/hooks/statusline ./cmd/hooks/statusline
	GOOS=darwin GOARCH=arm64 go build $(LDFLAGS) -o $(BUILD_DIR)/darwin-arm64/hooks/statusline ./cmd/hooks/statusline

build-windows:
	@echo "Building for Windows..."
	@mkdir -p $(BUILD_DIR)/windows-amd64/hooks
	GOOS=windows GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/windows-amd64/worker.exe ./cmd/worker
	GOOS=windows GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/windows-amd64/mcp-server.exe ./cmd/mcp
	GOOS=windows GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/windows-amd64/hooks/session-start.exe ./cmd/hooks/session-start
	GOOS=windows GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/windows-amd64/hooks/user-prompt.exe ./cmd/hooks/user-prompt
	GOOS=windows GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/windows-amd64/hooks/post-tool-use.exe ./cmd/hooks/post-tool-use
	GOOS=windows GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/windows-amd64/hooks/subagent-stop.exe ./cmd/hooks/subagent-stop
	GOOS=windows GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/windows-amd64/hooks/stop.exe ./cmd/hooks/stop
	GOOS=windows GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/windows-amd64/hooks/statusline.exe ./cmd/hooks/statusline

# Stop any running worker
stop-worker:
	@echo "Stopping worker..."
	@-pkill -TERM -f 'claude-mnemonic.*worker' 2>/dev/null || true
	@-pkill -TERM -f '\.claude-mnemonic/bin/worker' 2>/dev/null || true
	@-pkill -TERM -f '\.claude/plugins/.*/worker' 2>/dev/null || true
	@sleep 1
	@-pkill -9 -f 'claude-mnemonic.*worker' 2>/dev/null || true
	@-pkill -9 -f '\.claude-mnemonic/bin/worker' 2>/dev/null || true
	@-pkill -9 -f '\.claude/plugins/.*/worker' 2>/dev/null || true
	@-lsof -ti :37777 | xargs kill -9 2>/dev/null || true
	@sleep 1

# Start worker in background
start-worker:
	@echo "Starting worker..."
	@nohup $(STABLE_BIN)/worker > /tmp/claude-mnemonic-worker.log 2>&1 &
	@sleep 1
	@if curl -s http://localhost:37777/health > /dev/null 2>&1; then \
		echo "Worker started successfully (http://localhost:37777)"; \
	else \
		echo "Warning: Worker may not have started. Check /tmp/claude-mnemonic-worker.log"; \
	fi

# Restart worker
restart-worker: stop-worker start-worker

# Install to stable binary location and register with Claude Code
install: build stop-worker
	@echo "Installing claude-mnemonic..."
	@# Verify build output binaries exist
	@test -f $(BUILD_DIR)/worker || { echo "ERROR: $(BUILD_DIR)/worker not found. Build may have failed."; exit 1; }
	@test -f $(BUILD_DIR)/mcp-server || { echo "ERROR: $(BUILD_DIR)/mcp-server not found. Build may have failed."; exit 1; }
	@test -d $(BUILD_DIR)/hooks || { echo "ERROR: $(BUILD_DIR)/hooks not found. Build may have failed."; exit 1; }
	@# Install binaries to stable location (survives Claude Code updates)
	@mkdir -p $(STABLE_BIN)/hooks
	cp $(BUILD_DIR)/worker $(STABLE_BIN)/
	cp $(BUILD_DIR)/mcp-server $(STABLE_BIN)/
	cp $(BUILD_DIR)/hooks/* $(STABLE_BIN)/hooks/
	@echo "Binaries installed to $(STABLE_BIN)"
	@# Set up marketplace directory with wrapper scripts and metadata
	@mkdir -p $(HOME)/.claude/plugins/marketplaces/claude-mnemonic/.claude-plugin
	@mkdir -p $(HOME)/.claude/plugins/marketplaces/claude-mnemonic/hooks
	@mkdir -p $(HOME)/.claude/plugins/marketplaces/claude-mnemonic/commands
	@cp .claude-plugin/plugin.json $(HOME)/.claude/plugins/marketplaces/claude-mnemonic/.claude-plugin/
	@cp marketplace.json $(HOME)/.claude/plugins/marketplaces/claude-mnemonic/.claude-plugin/marketplace.json 2>/dev/null || true
	@cp hooks/hooks.json $(HOME)/.claude/plugins/marketplaces/claude-mnemonic/hooks/
	@cp hooks/session-start hooks/user-prompt hooks/post-tool-use hooks/stop hooks/subagent-stop hooks/statusline $(HOME)/.claude/plugins/marketplaces/claude-mnemonic/hooks/
	@chmod +x $(HOME)/.claude/plugins/marketplaces/claude-mnemonic/hooks/*
	@cp mcp-server $(HOME)/.claude/plugins/marketplaces/claude-mnemonic/
	@chmod +x $(HOME)/.claude/plugins/marketplaces/claude-mnemonic/mcp-server
	@cp commands/restart.md $(HOME)/.claude/plugins/marketplaces/claude-mnemonic/commands/
	@echo "Registering plugin with Claude Code..."
	@./scripts/register-plugin.sh "$(VERSION)"
	@$(MAKE) start-worker
	@echo "Installation complete!"

# Uninstall
uninstall: stop-worker
	@echo "Uninstalling..."
	@./scripts/unregister-plugin.sh
	rm -rf $(HOME)/.claude/plugins/marketplaces/claude-mnemonic
	@echo "Uninstallation complete!"

# Run tests (with FTS5 support)
# CLAUDE_MNEMONIC_MODEL_DIR points to a common model directory for tests.
# Run setup-models first to download models from Hugging Face.
test: setup-libs setup-models
	CLAUDE_MNEMONIC_MODEL_DIR=$$(pwd)/testdata/models go test $(BUILD_TAGS) -v -race ./...

# Run tests with coverage (with FTS5 support)
test-coverage: setup-libs setup-models
	CLAUDE_MNEMONIC_MODEL_DIR=$$(pwd)/testdata/models go test $(BUILD_TAGS) -v -race -coverprofile=coverage.out ./...
	go tool cover -html=coverage.out -o coverage.html
	@go tool cover -func=coverage.out | tail -1

# Run benchmarks
bench:
	go test -bench=. -benchmem ./...

# Run linter
lint:
	golangci-lint run ./...

# Format code
fmt:
	go fmt ./...

# Clean build artifacts
clean:
	rm -rf $(BUILD_DIR)
	rm -f coverage.out coverage.html

# Run worker in development mode
dev: worker
	./$(BUILD_DIR)/worker

# Download dependencies
deps:
	go mod download
	go mod tidy

# Build website for production
website:
	@echo "Building website..."
	@cd docs && npm install --silent && npm run build
	@echo "Website built to docs/dist/"

# Run website in development mode
dev-website:
	@echo "Starting website dev server..."
	@cd docs && npm install --silent && npm run dev

# Show help
help:
	@echo "Claude Mnemonic Build System"
	@echo ""
	@echo "Usage:"
	@echo "  make build          - Build all binaries"
	@echo "  make worker         - Build worker service only"
	@echo "  make mcp            - Build MCP server only"
	@echo "  make hooks          - Build hooks only"
	@echo "  make build-all      - Build for all platforms"
	@echo "  make install        - Install to Claude plugins directory (restarts worker)"
	@echo "  make uninstall      - Remove from Claude plugins directory"
	@echo "  make stop-worker    - Stop the running worker"
	@echo "  make start-worker   - Start the worker in background"
	@echo "  make restart-worker - Restart the worker"
	@echo "  make test           - Run tests"
	@echo "  make bench          - Run benchmarks"
	@echo "  make lint           - Run linter"
	@echo "  make fmt            - Format code"
	@echo "  make clean          - Clean build artifacts"
	@echo "  make dev            - Run worker in development mode"
	@echo "  make update-version - Update version in plugin metadata files"
	@echo "  make deps           - Download dependencies"
	@echo "  make website        - Build website for production"
	@echo "  make dev-website    - Run website dev server"
	@echo ""
	@echo "Variables:"
	@echo "  VERSION=$(VERSION)"
	@echo "  GOOS=$(GOOS)"
	@echo "  GOARCH=$(GOARCH)"
