.PHONY: build clean test fmt vet lint help gen-proto gen-proto-go gen-proto-py mod-tidy mod-vendor install

# project name
PROJECT_NAME := Conch

# Go commands
GOCMD := go
GOBUILD := $(GOCMD) build
GOCLEAN := $(GOCMD) clean
GOTEST := $(GOCMD) test
GOGET := $(GOCMD) get
GOMOD := $(GOCMD) mod

# binary output directory
BIN_DIR := bin

CONCH_AGENT_PROTO_DIR := ./api
CONCH_AGENT_GEN_DIR := ./api/go_proto
CONCH_PY_PROTO_DIR := ./api/py_proto
CLEANSCRIPT := ./scripts/cleancode.sh

# get all cmd directory subdirectories as binary names
CMDS := $(shell find cmd -mindepth 1 -maxdepth 1 -type d ! -name conch-unpack -exec basename {} \;)

export GO111MODULE=on

default: build

help: ## Show this help message
	@echo "available commands:"
	@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "  \033[36m%-15s\033[0m %s\n", $$1, $$2}'

gen-proto: gen-proto-go gen-proto-py ## Generate Go and Python protobuf code

gen-proto-go: ## Generate Go protobuf code
	@echo "installing proto tools (if not exist)..."
	@which protoc-gen-go >/dev/null 2>&1 || GOBIN=$(shell go env GOPATH)/bin go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.36.11
	@which protoc-gen-go-grpc >/dev/null 2>&1 || GOBIN=$(shell go env GOPATH)/bin go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.5.1

	@echo "generating Go proto code..."
	@mkdir -p $(CONCH_AGENT_GEN_DIR)
	@protoc \
		--proto_path=$(CONCH_AGENT_PROTO_DIR) \
		--go_out=$(CONCH_AGENT_GEN_DIR) \
		--go_opt=paths=source_relative \
		--go-grpc_out=$(CONCH_AGENT_GEN_DIR) \
		--go-grpc_opt=paths=source_relative,require_unimplemented_servers=false \
		$(CONCH_AGENT_PROTO_DIR)/*.proto;
	@echo "Go proto code generated to $(CONCH_AGENT_GEN_DIR)"

gen-proto-py: ## Generate Python protobuf code (auto-installs grpcio-tools if missing)
	@echo "ensuring grpcio-tools (for Python proto)..."
	@python -c "import grpc_tools.protoc" 2>/dev/null || python -m pip install grpcio-tools
	@echo "generating Python proto code..."
	@mkdir -p $(CONCH_PY_PROTO_DIR)
	@python -m grpc_tools.protoc \
		--proto_path=$(CONCH_AGENT_PROTO_DIR) \
		--python_out=$(CONCH_PY_PROTO_DIR) \
		--grpc_python_out=$(CONCH_PY_PROTO_DIR) \
		$(CONCH_AGENT_PROTO_DIR)/agent.proto
	@echo "Fixing GRPC import in agent_pb2_grpc.py..."
	@python -c "import pathlib; p=pathlib.Path('$(CONCH_PY_PROTO_DIR)/agent_pb2_grpc.py'); p.write_text(p.read_text().replace('import agent_pb2 as agent__pb2', 'from . import agent_pb2 as agent__pb2'))"
	@python -c "import pathlib; pathlib.Path('$(CONCH_PY_PROTO_DIR)/__init__.py').write_text('# Auto-generated by Makefile gen-proto-py\nfrom . import agent_pb2, agent_pb2_grpc\n')"
	@echo "Python proto code generated to $(CONCH_PY_PROTO_DIR)"

build: 
	./scripts/conch-env-setup.sh build

build-offline: gen-proto
	@echo "syncing dependency manifests from image backup..."
	@cp /go/go.mod.backup ./go.mod
	@cp /go/go.sum.backup ./go.sum
	@echo "building binaries using image cache..."
	@mkdir -p $(BIN_DIR)
	@for cmd in $(CMDS); do \
		echo "building cmd/$$cmd..."; \
		$(GOBUILD) -mod=readonly -o $(BIN_DIR)/$$cmd ./cmd/$$cmd; \
	done
	@git checkout go.mod go.sum 2>/dev/null || true

build-%: ## Build specific binary (e.g., make build-conchd)
	@echo "building cmd/$*..."
	@mkdir -p $(BIN_DIR)
	$(GOBUILD) -o $(BIN_DIR)/$* ./cmd/$*

clean: ## Clean build artifacts
	@echo "cleaning build artifacts..."
	$(GOCLEAN)
	rm -rf $(BIN_DIR)
	rm -rf $(CONCH_AGENT_GEN_DIR)
	rm -rf $(CONCH_PY_PROTO_DIR)
	@echo "cleaning completed"

test: ## Run all tests
	@echo "running tests..."
	$(GOTEST) -v ./...

test-coverage: ## Run tests with coverage report
	@echo "running tests and generating coverage report..."
	$(GOTEST) -v -coverprofile=coverage.out ./...
	$(GOCMD) tool cover -html=coverage.out -o coverage.html
	@echo "coverage report generated: coverage.html"

fmt: cleancode ## Format code (go fmt + cleancode)
	@echo "formatting code with go fmt..."
	$(GOCMD) fmt ./...
	@echo "code formatting completed"

vet: ## Run go vet
	@echo "running go vet..."
	$(GOCMD) vet ./...

lint: fmt vet ## Tidy go modules

mod-tidy: ## Tidy go modules
	@echo "tidying dependencies..."
	$(GOMOD) tidy

mod-vendor: ## Download dependencies to vendor directory
	@echo "downloading dependencies to vendor directory..."
	$(GOMOD) vendor

install:
	./scripts/conch-env-setup.sh install

cleancode: ## Clean code (remove trailing spaces/CR)
	@echo "cleaning code..."
	@if [ ! -f $(CLEANSCRIPT) ]; then \
		echo "Error: cleancode script not found at $(CLEANSCRIPT)"; \
		exit 1; \
	fi
	@if [ ! -x $(CLEANSCRIPT) ]; then \
		chmod +x $(CLEANSCRIPT); \
	fi
	@$(CLEANSCRIPT) > /dev/null 2>&1
	@echo "code cleaning completed"