SHELL := /bin/bash

GO ?= go
DOCKER ?= docker

HOST_GOOS ?= $(shell $(GO) env GOOS)
HOST_GOARCH ?= $(shell $(GO) env GOARCH)

# Build target defaults to the local environment; callers can override.
GOOS ?= $(HOST_GOOS)
GOARCH ?= $(HOST_GOARCH)

APP_NAME ?= drive9-server

BIN_DIR ?= bin
# Use an absolute GOBIN for tool installation; `go install` is more predictable
# with an absolute path than a repo-relative bin dir.
BIN_DIR_ABS := $(abspath $(BIN_DIR))
SERVER_BIN ?= $(BIN_DIR)/$(APP_NAME)

VERSION ?=
GIT_HASH ?= $(shell git rev-parse HEAD 2>/dev/null || echo unknown)
GIT_BRANCH ?= $(shell git rev-parse --abbrev-ref HEAD 2>/dev/null || echo unknown)
BUILD_TIME ?= $(shell date -u '+%Y-%m-%dT%H:%M:%SZ')

GOLANGCI_LINT_VERSION ?= v2.5.0
GOLANGCI_LINT_BIN ?= $(BIN_DIR)/golangci-lint

IMAGE_REPO ?= drive9-server
IMAGE_TAG ?= latest
IMAGE ?= $(IMAGE_REPO):$(IMAGE_TAG)
LINT_TIMEOUT ?= 10m
TEST_TIMEOUT ?= 10m
TEST_P ?=
TEST_RUN ?=
TEST_PKGS ?= ./...

BUILDINFO_LDFLAGS = -X github.com/mem9-ai/drive9/pkg/buildinfo.Version=$(if $(VERSION),$(VERSION),dev) \
	-X github.com/mem9-ai/drive9/pkg/buildinfo.GitHash=$(GIT_HASH) \
	-X github.com/mem9-ai/drive9/pkg/buildinfo.GitBranch=$(GIT_BRANCH) \
	-X github.com/mem9-ai/drive9/pkg/buildinfo.BuildTime=$(BUILD_TIME)

.PHONY: mod test test-failpoint test-podman fmt lint install-lint build build-server build-billing-worker run-server-local e2e-local blackbox-local docker-build swagger swagger-check

mod:
	$(GO) mod tidy
	$(GO) mod download

# Run tests. TiDB-backed suites reuse DRIVE9_TEST_TIDB_DSN when provided. When
# it is unset and podman is available locally, automatically configure the
# podman-backed testcontainers environment before running go test.
# - TEST_P to pass `-p <value>` to `go test`
# - TEST_RUN to pass `-run <regex>` to `go test`
# - TEST_PKGS to choose the packages under test (defaults to `./...`).
test:
	@set -euo pipefail; \
	test_p_flag=""; \
	test_run_flag=""; \
	if [ -n "$(TEST_P)" ]; then \
		test_p_flag="-p $(TEST_P)"; \
	fi; \
	if [ -n "$(TEST_RUN)" ]; then \
		test_run_flag="-run $(TEST_RUN)"; \
	fi; \
	if [ -z "$${DRIVE9_TEST_TIDB_DSN:-}" ] && command -v podman >/dev/null 2>&1; then \
		if podman_env="$$(bash -lc 'source ./scripts/test-podman.sh && env | grep -E "^(DOCKER_HOST|TESTCONTAINERS_RYUK_DISABLED)="')"; then \
			while IFS= read -r line; do \
				export "$$line"; \
			done <<< "$$podman_env"; \
		else \
			echo "make test: Podman testcontainers setup unavailable, falling back to default runtime" >&2; \
		fi; \
	fi; \
	$(GO) test $$test_p_flag $$test_run_flag -v -timeout $(TEST_TIMEOUT) $(TEST_PKGS)

# Run only failpoint-tagged tests through repository-wide instrumentation.
# Do not run this concurrently with the normal test target because failpoint-ctl
# rewrites the source tree while the tests are running.
test-failpoint:
	./scripts/run_failpoint_tests.py

fmt:
	$(MAKE) install-lint
	$(GOLANGCI_LINT_BIN) run --fix

# Regenerate the three OpenAPI documents under docs/api/ from the endpoint
# registry (pkg/server/openapi_registry.go), then verify they are up to date.
# The check-only target is CI-friendly: exit non-zero when docs are stale.
swagger:
	go run ./cmd/swagger-gen $(SWAGGER_ARGS)
	$(MAKE) swagger-check

swagger-check:
	go run ./cmd/swagger-gen --check $(SWAGGER_ARGS)

lint:
	$(MAKE) install-lint
	$(GOLANGCI_LINT_BIN) run --timeout $(LINT_TIMEOUT)

install-lint:
	@echo "Checking for golangci-lint..."
	@if [ ! -x "$(GOLANGCI_LINT_BIN)" ]; then \
		echo "Installing golangci-lint $(GOLANGCI_LINT_VERSION) to $(BIN_DIR)..."; \
		mkdir -p "$(BIN_DIR)"; \
		GOBIN="$(BIN_DIR_ABS)" $(GO) install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION); \
	else \
		echo "golangci-lint already installed at $(GOLANGCI_LINT_BIN)"; \
	fi

build: build-server build-billing-worker

build-server:
	mkdir -p $(BIN_DIR)
	CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(GOARCH) $(GO) build -ldflags "$(BUILDINFO_LDFLAGS)" -o $(SERVER_BIN) ./cmd/drive9-server

build-billing-worker:
	mkdir -p $(BIN_DIR)
	CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(GOARCH) $(GO) build -ldflags "$(BUILDINFO_LDFLAGS)" -o bin/drive9-billing-worker ./cmd/drive9-billing-worker

run-server-local: build-server
	@DRIVE9_TENANT_PROVIDER="$${DRIVE9_TENANT_PROVIDER:-local}" "./$(SERVER_BIN)"

# Graft this repo's drive9-server onto mem9-ai/drive9 e2e (clone or
# DRIVE9_UPSTREAM_DIR). Extra flags:
#   make e2e-local
#   make e2e-local E2E_LOCAL_ARGS="--keep-server"
#   make e2e-local E2E_LOCAL_ARGS="--no-build"
e2e-local:
	bash scripts/e2e-local.sh $(E2E_LOCAL_ARGS)

# Graft this repo's drive9-server onto mem9-ai/drive9 blackbox (clone or
# DRIVE9_UPSTREAM_DIR). Extra flags:
#   make blackbox-local
#   make blackbox-local BLACKBOX_ARGS="--group community"
#   make blackbox-local BLACKBOX_ARGS="--module community.pjdfstest"
#   make blackbox-local BLACKBOX_ARGS="--all --strict-prereqs"
#   make blackbox-local BLACKBOX_ARGS="--no-build"
blackbox-local:
	bash scripts/blackbox-local.sh $(BLACKBOX_ARGS)

DOCKER_BUILD_ARGS ?=

docker-build: build-server build-billing-worker
	$(DOCKER) build $(DOCKER_BUILD_ARGS) -t $(IMAGE) .
