# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
#   🦫 FAST-TIME-SERVER - Makefile
#   (single-file Go project: main.go + main_test.go)
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
#
# Author : Mihai Criveti
# Usage  : make <target>   or just `make help`
#
# help: 🦫 FAST-TIME-SERVER (Go build & automation helpers)
# ─────────────────────────────────────────────────────────────────────────

# =============================================================================
# 📖 DYNAMIC HELP
# =============================================================================
.PHONY: help
help:
	@grep '^# help\:' $(firstword $(MAKEFILE_LIST)) | sed 's/^# help\: //'

# =============================================================================
# 📦 PROJECT METADATA (variables, colours)
# =============================================================================
MODULE          := github.com/yourorg/fast-time-server
BIN_NAME        := fast-time-server
VERSION         ?= $(shell git describe --tags --dirty --always 2>/dev/null || echo "v0.0.0-dev")

DIST_DIR        := dist
COVERPROFILE    := $(DIST_DIR)/coverage.out
COVERHTML       := $(DIST_DIR)/coverage.html

GO              ?= go
GOOS            ?= $(shell $(GO) env GOOS)
GOARCH          ?= $(shell $(GO) env GOARCH)

LDFLAGS         := -s -w -X 'main.appVersion=$(VERSION)'

ifeq ($(shell test -t 1 && echo tty),tty)
C_BLUE  := \033[38;5;75m
C_RESET := \033[0m
else
C_BLUE  :=
C_RESET :=
endif

# =============================================================================
# 🔧 TOOLING
# =============================================================================
# help: 🔧 TOOLING
# help: tools                 - Install / update golangci-lint & staticcheck

GOBIN := $(shell $(GO) env GOPATH)/bin

tools: $(GOBIN)/golangci-lint $(GOBIN)/staticcheck
$(GOBIN)/golangci-lint: ;	@$(GO) install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
$(GOBIN)/staticcheck:      ;	@$(GO) install honnef.co/go/tools/cmd/staticcheck@latest

# =============================================================================
# 📂 MODULE & FORMAT
# =============================================================================
# help: 📂 MODULE & FORMAT
# help: tidy                  - go mod tidy + verify
# help: fmt                   - Run gofmt & goimports

tidy:
	@$(GO) mod tidy
	@$(GO) mod verify

fmt:
	@$(GO) fmt ./...
	@go run golang.org/x/tools/cmd/goimports@latest -w .

# =============================================================================
# 🔍 LINTING & STATIC ANALYSIS
# =============================================================================
# help: 🔍 LINTING & STATIC ANALYSIS
# help: vet                   - go vet
# help: staticcheck           - Run staticcheck
# help: lint                  - Run golangci-lint
# help: pre-commit            - Run all configured pre-commit hooks
.PHONY: vet staticcheck lint pre-commit

vet:
	@$(GO) vet ./...

staticcheck: tools
	@staticcheck ./...

lint: tools
	@golangci-lint run

pre-commit:                 ## Run pre-commit hooks on all files
	@command -v pre-commit >/dev/null 2>&1 || { \
	    echo '✖ pre-commit not installed → pip install --user pre-commit'; exit 1; }
	@pre-commit run --all-files --show-diff-on-failure

# =============================================================================
# 🧪 TESTS & COVERAGE
# =============================================================================
# help: 🧪 TESTS & COVERAGE
# help: test                  - Run unit tests (race)
# help: coverage              - Generate HTML coverage report

test:
	@$(GO) test -race -timeout=90s ./...

coverage:
	@mkdir -p $(DIST_DIR)
	@$(GO) test ./... -covermode=count -coverprofile=$(COVERPROFILE)
	@$(GO) tool cover -html=$(COVERPROFILE) -o $(COVERHTML)
	@echo "$(C_BLUE)HTML coverage → $(COVERHTML)$(C_RESET)"

# =============================================================================
# 🛠 BUILD & RUN
# =============================================================================
# help: 🛠 BUILD & RUN
# help: build                 - Build binary into ./dist
# help: install               - go install into GOPATH/bin
# help: release               - Cross-compile (honours GOOS/GOARCH)
# help: run                   - Build then run (stdio transport)
# help: run-stdio             - Alias for "run"
# help: run-http              - Run HTTP  transport on :8080  (POST JSON-RPC)
# help: run-sse               - Run SSE   transport on :8080  (/sse, /messages)
# help: run-dual              - Run BOTH  SSE & HTTP on :8080 (/sse, /messages, /http)
# help: run-rest              - Run REST API on :8080  (/api/v1/*)

build: tidy
	@mkdir -p $(DIST_DIR)
	@$(GO) build -trimpath -ldflags '$(LDFLAGS)' -o $(DIST_DIR)/$(BIN_NAME) .

install:
	@$(GO) install -trimpath -ldflags '$(LDFLAGS)' .

release:
	@mkdir -p $(DIST_DIR)/$(GOOS)-$(GOARCH)
	@GOOS=$(GOOS) GOARCH=$(GOARCH) CGO_ENABLED=0 \
	  $(GO) build -trimpath -ldflags '$(LDFLAGS)' \
	  -o $(DIST_DIR)/$(GOOS)-$(GOARCH)/$(BIN_NAME) .

# ────── run helpers ────────────────────────────────────────────────────────
run: build
	@$(DIST_DIR)/$(BIN_NAME) -transport=stdio

run-stdio: run			# simple alias

run-http: build
	@$(DIST_DIR)/$(BIN_NAME) -transport=http -addr=0.0.0.0:8080

run-sse: build
	@$(DIST_DIR)/$(BIN_NAME) -transport=sse  -listen=0.0.0.0 -port=8080

run-dual: build
	@$(DIST_DIR)/$(BIN_NAME) -transport=dual -port=8080

run-rest: build
	@$(DIST_DIR)/$(BIN_NAME) -transport=rest -port=8080

# =============================================================================
# 🐳 DOCKER
# =============================================================================
# help: 🐳 DOCKER
# help: docker-build          - Build container image
# help: docker-run            - Run container on :8080 (HTTP transport)
# help: docker-run-sse        - Run container on :8080 (SSE transport)
# help: docker-run-sse-auth   - Run SSE with Bearer token auth (TOKEN env or default)

IMAGE ?= $(BIN_NAME):$(VERSION)
TOKEN ?= secret123            # override:  make docker-run-sse-auth TOKEN=mytoken

docker-build:
	@docker build --build-arg VERSION=$(VERSION) -t $(IMAGE) .
	@docker images $(IMAGE)

docker-run: docker-build
	@docker run --rm -p 8080:8080 $(IMAGE) -transport=http -addr=0.0.0.0:8080

docker-run-sse: docker-build
	@docker run --rm -p 8080:8080 $(IMAGE) -transport=sse -listen=0.0.0.0 -port=8080

docker-run-sse-auth: docker-build
	@docker run --rm -p 8080:8080 \
	    -e AUTH_TOKEN=$(TOKEN) \
	    $(IMAGE) -transport=sse -listen=0.0.0.0 -port=8080 -auth-token=$(TOKEN)

# =============================================================================
# 📚 MCP RESOURCES & PROMPTS TESTING
# =============================================================================
# help: 📚 MCP RESOURCES & PROMPTS
# help: test-resources        - Test MCP resources via REST API
# help: test-prompts          - Test MCP prompts via REST API
# help: test-mcp              - Test all MCP features (resources + prompts)

.PHONY: test-resources test-prompts test-mcp

test-resources:
	@echo "$(C_BLUE)➜ Testing MCP Resources...$(C_RESET)"
	@curl -s http://localhost:8080/api/v1/resources | jq .
	@echo "\n$(C_BLUE)➜ Timezone Info:$(C_RESET)"
	@curl -s http://localhost:8080/api/v1/resources/timezone-info | jq '.timezones[0]'
	@echo "\n$(C_BLUE)➜ Current World Times:$(C_RESET)"
	@curl -s http://localhost:8080/api/v1/resources/current-world | jq .

test-prompts:
	@echo "$(C_BLUE)➜ Testing MCP Prompts...$(C_RESET)"
	@curl -s http://localhost:8080/api/v1/prompts | jq .
	@echo "\n$(C_BLUE)➜ Compare Timezones:$(C_RESET)"
	@curl -s -X POST http://localhost:8080/api/v1/prompts/compare_timezones/execute \
	     -H "Content-Type: application/json" \
	     -d '{"timezones":"UTC,America/New_York,Asia/Tokyo"}' | jq .

test-mcp: test-resources test-prompts
	@echo "\n$(C_BLUE)✔ MCP Features Test Complete$(C_RESET)"

# =============================================================================
# 🚀 BENCHMARKING (hey)
# =============================================================================
# help: 🚀 BENCHMARKING
# help: bench                 - Run HTTP load test using 'hey' on /http (run make dual first)

.PHONY: bench

bench:
	@command -v hey >/dev/null || { echo '"hey" not installed'; exit 1; }
	@echo "➜ load-test convert_time via /http"
	@hey -m POST -T 'application/json' \
	     -D payload.json \
	     -n 100000 -c 100 http://localhost:8080/http

# =============================================================================
# 🧹 CLEANUP
# =============================================================================
# help: 🧹 CLEANUP
# help: clean                 - Remove build & coverage artefacts

clean:
	@rm -rf $(DIST_DIR) $(COVERPROFILE) $(COVERHTML)
	@echo "Workspace clean ✔"

# ---------------------------------------------------------------------------
# Default goal
# ---------------------------------------------------------------------------
.DEFAULT_GOAL := help
