ROOT := github.com/tidbcloud/shared-provider
IMG_PREFIX := shared-provider

# Setting SHELL to bash allows bash commands to be executed by recipes.
# This is a requirement for 'setup-envtest.sh' in the test target.
# Options are set to exit when a recipe line exits non-zero or a piped command fails.
SHELL = /usr/bin/env bash -o pipefail
.SHELLFLAGS = -ec

REPO ?= gcr.io/pingcap-public
VERSION ?= "latest"

KUBECONFIG ?= $(HOME)/.kube/config
INFRA_KUBECONFIG ?= $(HOME)/.kube/config

TARGETS ?= manager dispatcher
KUBECTL ?= kubectl

.PHONY: build

all: build

##@ General

# The help target prints out all targets with their descriptions organized
# beneath their categories. The categories are represented by '##@' and the
# target descriptions by '##'. The awk commands is responsible for reading the
# entire set of makefiles included in this invocation, looking for lines of the
# file as xyz: ## something, and then pretty-format the target and help. Then,
# if there's a line with ##@ something, that gets pretty-printed as a category.
# More info on the usage of ANSI control characters for terminal formatting:
# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters
# More info on the awk command:
# http://linuxcommand.org/lc3_adv_awk.php

help: ## Display this help.
	@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n  make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf "  \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)

##@ Development

# Image URL to use all building/pushing image targets
# Produce CRDs that work back to Kubernetes 1.11 (no version conversion)
CRD_OPTIONS := "crd:trivialVersions=true,preserveUnknownFields=false"
manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
	$(CONTROLLER_GEN) $(CRD_OPTIONS) webhook \
		paths=github.com/tidbcloud/infra-api/api/... \
		output:crd:artifacts:config=deploy/crd/infra/bases \
		output:webhook:artifacts:config=deploy/webhook
	$(CONTROLLER_GEN) rbac:roleName=dispatcher \
		paths=./pkg/dispatcher \
		output:rbac:artifacts:config=deploy/components/dispatcher/rbac

reviewable: build lint unit-test integration ## Make a PR ready for review.

lint: golangci-lint
	$(GOLANGCI_LINT) run ./...

unit-test: ## Run tests.
	mkdir -p coverage
	go test -v `go list ./... |grep -v tests` -coverprofile coverage/ut.out

ENVTEST_ASSETS_DIR=$(shell pwd)/testbin
PATH := $(PWD)/testbin/bin:$(PATH)
export ACK_GINKGO_DEPRECATIONS=1.16.4
integration: ginkgo
	mkdir -p testbin
	test -f ${ENVTEST_ASSETS_DIR}/setup-envtest.sh || curl -sSLo ${ENVTEST_ASSETS_DIR}/setup-envtest.sh https://raw.githubusercontent.com/kubernetes-sigs/controller-runtime/v0.7.2/hack/setup-envtest.sh
	. ${ENVTEST_ASSETS_DIR}/setup-envtest.sh && \
	fetch_envtest_tools $(ENVTEST_ASSETS_DIR) && \
	setup_envtest_env $(ENVTEST_ASSETS_DIR) && \
	$(GINKGO) -outputdir=. -focus=$(focus) -slowSpecThreshold=300 ./tests/integration/...



GENHTML=genhtml  # part of lcov
coverage: gcov2lcov ## generate coverage html under coverage/ after running tests
	$(GCOV2LCOV) -infile=coverage/ut.out -outfile=coverage/ut.out.lcov
	$(GENHTML) -o coverage/ut_html coverage/ut.out.lcov

e2e: pulumi ginkgo
	VAR_IMG_HUB=ecr ./hack/tests/e2e.sh

compatibility-test: pulumi ginkgo
	VAR_IMG_HUB=ecr ./hack/tests/compatibility.sh

build:
	./hack/build/go.sh $(TARGETS)

build-in-docker:
	./hack/build/in_docker.sh $(TARGETS)

# NOTE(liubo02): now make push can build and push image
docker-build: build-in-docker
	./hack/image/build.sh $(TARGETS)

docker-push:
	echo "Deprecated: Please use make push to build and push image directly"
	./hack/push-image.sh $(TARGETS)

# TODO(liubo02): add a cmd to build and push to kind
push: build-in-docker
	./hack/image/build.sh --push $(TARGETS)

deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
	./hack/deploy.sh install $(TARGETS)

undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/config.
	./hack/deploy.sh uninstall $(TARGETS)

local-cluster-up: kind
	$(KIND) create cluster --name shared-provider \
		--config ./deploy/kind/config.yaml \
		--image kindest/node:v1.19.7 \
		--kubeconfig $(KUBECONFIG)

local-cluster-down: kind
	$(KIND) delete cluster --name shared-provider --kubeconfig $(KUBECONFIG)

local-cluster-load-image: kind
	KIND=$(KIND) VAR_IMG_HUB=local ./hack/push-image.sh $(TARGETS)


version: git-semver
	$(GIT_SEMVER)


CONTROLLER_GEN = $(shell pwd)/bin/controller-gen
controller-gen: ## Download controller-gen locally if necessary.
	$(call go-get-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen@v0.4.1)

KUSTOMIZE = $(shell pwd)/bin/kustomize
kustomize: ## Download kustomize locally if necessary.
	$(call go-get-tool,$(KUSTOMIZE),sigs.k8s.io/kustomize/kustomize/v3@v3.8.7)

GOLANGCI_LINT = $(shell pwd)/bin/golangci-lint
golangci-lint:
	$(call go-get-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/cmd/golangci-lint@v1.45.2)

KIND = $(shell pwd)/bin/kind
kind:
	$(call go-get-tool,$(KIND),sigs.k8s.io/kind/cmd/kind@v0.11.1)

PULUMI = $(shell pwd)/bin/pulumi
pulumi:
	BIN=$(PULUMI) ./tools/pulumi/install.sh
	# cd ./cd && npm install

GINKGO = $(shell pwd)/bin/ginkgo
ginkgo:
	$(call go-get-tool,$(GINKGO),github.com/onsi/ginkgo/ginkgo@v1.16.5)

GCOV2LCOV = $(shell pwd)/bin/gcov2lcov
gcov2lcov:
	$(call go-get-tool, $(GCOV2LCOV),github.com/jandelgado/gcov2lcov@v1.0.5)

GIT_SEMVER = $(shell pwd)/bin/git-semver
git-semver:
	$(call go-get-tool, $(GIT_SEMVER),github.com/mdomke/git-semver/v6@v6.1.1)


# go-get-tool will 'go get' any package $2 and install it to $1.
PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST))))
define go-get-tool
@[ -f $(1) ] || { \
set -e ;\
TMP_DIR=$$(mktemp -d) ;\
cd $$TMP_DIR ;\
go mod init tmp ;\
echo "Downloading $(2)" ;\
CGO_ENABLED=0 GOBIN=$(PROJECT_DIR)/bin go install $(2) ;\
rm -rf $$TMP_DIR ;\
}
endef
