.DEFAULT_GOAL := help

PROJECT_PATH := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
OUTPUT_PATH := $(PROJECT_PATH)/_output

TAG ?=  $(shell git -C "$(PROJECT_PATH)" rev-parse HEAD)
ifdef VERSION
override TAG = $(VERSION)
endif

ENCODED := $(shell echo "$$DB_PASSWORD")
ENCODED_PWD := $(shell python3 -c 'import urllib.parse; db="$(ENCODED)"; print(urllib.parse.quote(db))')
DEFAULT_API_NAME ?= api.go

OAPI_VERSION=v1.12.4
GO_VERSION=1.18
GO_MOCKGEN_VERSION=v1.3.7

define setup_env
	$(eval include $(PROJECT_PATH)/.devcontainer/LoadLocalEnv)
endef

.PHONY: run
run:
	$(call setup_env)
	go mod tidy && go run cmd/server/main.go

.PHONY: docker-build
docker-build: ## Build container image
	docker build --build-arg PAT=$(PAT) --tag $(ALCHEMY_REGISTRY):$(TAG) --tag $(ALCHEMY_REGISTRY):latest .

.PHONY: docker-push
docker-push: ## Pushes the image built with docker-build
	docker push --all-tags $(ALCHEMY_REGISTRY)

.PHONY: docker-clean
docker-clean: ## Deletes pushed image and any leftovers to be tidy
	docker rmi -f $(ALCHEMY_REGISTRY):$(TAG)
	#delete any dangling images
	docker image prune -f

.PHONY: unit
unit: ## Run unit tests
	mkdir -p "$(OUTPUT_PATH)"
	go install github.com/jstemmer/go-junit-report/v2@v2.0.0
	go test ./... -v -covermode=count -coverprofile=$(OUTPUT_PATH)/cover.out | tee /dev/stderr | go-junit-report -set-exit-code > $(OUTPUT_PATH)/report.xml

.PHONY: unit-local
unit-local: ## Run unit tests locally
	mkdir -p "$(OUTPUT_PATH)"
	go test ./... -v -covermode=count -coverprofile=$(OUTPUT_PATH)/cover.out | tee /dev/stderr | go-junit-report -set-exit-code > $(OUTPUT_PATH)/report.xml

.PHONY: unit-coverage
unit-coverage: unit ## Runs unit tests and generates a html coverage report
	go tool cover -html=$(OUTPUT_PATH)/cover.out

.PHONY: unit-coverage-cobertura
unit-coverage-cobertura: ## Runs unit tests and generates a cobertura coverage report
	go install github.com/boumenot/gocover-cobertura@v1.2.0
	gocover-cobertura < $(OUTPUT_PATH)/cover.out > $(OUTPUT_PATH)/coverage.xml

.PHONY: migrate-up
migrate-up: ## Run migrations
	migrate -path "migrations" -database "mysql://$(DB_USER):$(ENCODED_PWD)@tcp($(DB_HOST):$(DB_PORT))/$(DB_NAME)" up

.PHONY: migrate-down
migrate-down: ## Revert migrations
	migrate -path "migrations" -database "mysql://$(DB_USER):$(ENCODED_PWD)@tcp($(DB_HOST):$(DB_PORT))/$(DB_NAME)" down

.PHONY: migrate-drop
migrate-drop: ## Drop all tables
	migrate -path "migrations" -database "mysql://$(DB_USER):$(ENCODED_PWD)@tcp($(DB_HOST):$(DB_PORT))/$(DB_NAME)" drop

.PHONY: gen-api-v1
gen-api-v1: ## generates public api interfaces
	docker container run --rm -v $(PWD):/app golang:$(GO_VERSION) sh -c "go install github.com/deepmap/oapi-codegen/cmd/oapi-codegen@$(OAPI_VERSION) && \
    cd /app && \
    oapi-codegen --config api-config.yaml ./api/v1/v1.yaml | sed 's/V1/v1/g' | sed 's/Id$(WORD_END)/ID/g' | sed 's/Guid/GUID/g' | sed 's/Sku/SKU/g' | sed 's/Qoh/QOH/g' | sed 's/float32/float64/g' | sed 's/Url/URL/g' > ./api/v1/$(DEFAULT_API_NAME)"

.PHONY: generate-api-docs
generate-api-docs:  ## generate API Documentation
	# requires the redoc-cli, you can install it with: npm i -g redoc-cli
	mkdir -p docs
	redoc-cli bundle --output docs/index.html api/v1/v1.yaml

.PHONY: mockery-mock-gen
mockery-mock-gen: ## make mockery-mock-gen will generate mocks for changed sources, make -B mockery-mock-gen will generate mocks for all sources
	make -f Makefile.mock mockery-gen

.PHONY: api-watch
api-watch: ## Start rest api and listen to changes
	# you may want to run "ulimit -n 10000" on MACOS
	reflex -d none --start-service -r '.(go|tpl|tmpl)' -R '^vendor/' -R ".git" go run ./cmd/server

.PHONY: lint
lint: ## Checks code formatting/quality/security
	docker run --rm -v $(PROJECT_PATH):/app -v ~/.gitconfig:/etc/gitconfig -w /app golangci/golangci-lint:v1.52.2 golangci-lint run -v --timeout=5m

.PHONY: docker-build-local
docker-build-local: ## Build local callisto container image
	docker build --build-arg PAT=$(PAT) -t callisto-so-bff -f ./local-deployment/docker/dockerfile .

.PHONY: local-deploy-apply
local-deploy-apply:
	kubectl create namespace callisto-so-bff
	kustomize build ./local-deployment/overlays/local | kubectl -n callisto-so-bff apply -f -

.PHONY: local-deploy-delete
local-deploy-delete:
	kustomize build ./local-deployment/overlays/local | kubectl -n callisto-so-bff delete -f -
	kubectl delete namespace callisto-so-bff

gh-actions-integration:
	mkdir -p "$(OUTPUT_PATH)"
	go install github.com/jstemmer/go-junit-report/v2@v2.0.0
	ENVIRONMENT_STORAGE=LOCAL LOCAL_CONFIG=$(PROJECT_PATH)/env.gh-actions.json ENVIRONMENT_CONFIG=$(PROJECT_PATH)/env.gh-actions.json \
		go test ./integration_tests/... -tags=integration -v -count=1 -covermode=count -coverpkg=./internal/... -coverprofile=$(OUTPUT_PATH)/integration_cover.out  \
		| tee /dev/stderr \
		| go-junit-report -set-exit-code >$(OUTPUT_PATH)/integration_report.xml

integration-coverage-cobertura: ## Generates a cobertura coverage report based on the integration tests output
	go install github.com/boumenot/gocover-cobertura@v1.2.0
	gocover-cobertura < $(OUTPUT_PATH)/integration_cover.out > $(OUTPUT_PATH)/integration_coverage.xml

help:
	@grep -E '^[a-zA-Z._-]+:.*?## .*$$' $(firstword $(MAKEFILE_LIST)) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
