# Build tools are savied in TOOLS_BIN_PATH.
TOOLS_BIN_PATH := $(shell pwd)/tools/bin

# Tools installed by go install in makefile are savied in TOOLS_BIN_PATH.
# They don't pollute the user development environment.
PATH := $(TOOLS_BIN_PATH):$(PATH)
ENVS := PATH='$(PATH)'
ENVS += GOBIN='$(TOOLS_BIN_PATH)'
ENVS += GOPRIVATE=github.com/pingcap
ENVS += GO111MODULE=auto
SHELL := env ${ENVS} $(shell which bash)


default: dev_tools

# Tools code.
#
# Example:
#   make tools/bin/ginkgo
tools/bin:
	@mkdir -p $(TOOLS_BIN_PATH)

tools/bin/ginkgo: tools/bin
	@go install github.com/onsi/ginkgo/ginkgo@latest

tools/bin/tcctl: tools/bin
	@go install github.com/pingcap/test-infra/tools/tcctl@latest

tools/bin/golangci-lint:
	@curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(TOOLS_BIN_PATH) v1.43.0

tools/bin/mockgen:
	@go install github.com/golang/mock/mockgen@v1.6.0

dev_tools: tools/bin/ginkgo tools/bin/tcctl


# Build code.
#
# Example:
#   make build -j
#   make testcase/examples/examples.test
#   make build/bin/testcase/examples/examples.test

BUILD_PATH := $(shell pwd)/build
BUILD_BIN_BASENAME := build/bin/
BUILD_BIN_PATH := $(shell pwd)/build/bin
GINKGO_FLAGS := -ldflags '-w -s'

# Gather all suites in testcase directory. Each suite looks like `testcase/xxx/yyy`.
ALL_SUITES := $(shell find testcase -name '*_suite_test.go' | xargs -I{} dirname {})
# Target for each suite looks like `testcase/xxx/yyy/yyy.test`.
# For example, `make testcase/examples/examples.test` builds examples suite.
ALL_SUITES_TARGETS := $(join ${ALL_SUITES},$(addprefix /,$(addsuffix .test,$(notdir ${ALL_SUITES}))))
# Target for each build binary looks like `build/bin/testcase/xxx/yyy/yyy.test`.
# For example, `make build/bin/testcase/examples/examples.test` copy
# examples suite's test binary to build bin path.
BUILD_BINARIES_TARGETS := $(addprefix $(BUILD_BIN_BASENAME), ${ALL_SUITES_TARGETS})

$(BUILD_BIN_BASENAME):
	@mkdir -p  $(BUILD_BIN_PATH)

$(ALL_SUITES_TARGETS): tools/bin/ginkgo
	@echo + gingo build $(GINKGO_FLAGS)
	@cd $(dir $@) && ginkgo build $(GINKGO_FLAGS)

$(BUILD_BINARIES_TARGETS): build/bin/%: % $(BUILD_BIN_BASENAME)
# `mkdir -p` can run in parallel while `cp --parents` may cause race condition,
# so we do `mkdir -p` before cp binaries.
	@mkdir -p "$(BUILD_BIN_PATH)/$(dir $(<))"
	@cp $< "$(BUILD_BIN_PATH)/$(<)"

# NOTE: copy Dockerfile to build directory to keep backward compatibility with CI.
.PHONY: build
build: $(BUILD_BINARIES_TARGETS)
	@cp Dockerfile build/

.PHONY: clean
clean:
	@rm -rf $(BUILD_PATH)
	@rm -f $(ALL_SUITES_TARGETS)

.PHONY: image
image: build
	@cp Dockerfile build/
	docker build -t endless:debug build/ -f Dockerfile

# Test code.
#
# Example:
#   make unittest
#   make test

.PHONY: unittest
unittest:
	go test ./pkg/...

.PHONY: test
test: unittest

# Check code.
#
# Example:
#   make check

.PHONY: check-tidy check-gogenerate check-fmt lint check

check-tidy:
	@echo "go mod tidy"
	@./scripts/check-tidy.sh

check-gogenerate: tools/bin/mockgen
	@echo "go genenrate ./..."
	@./scripts/check-gogenerate.sh

check-fmt:
	@echo "go fmt ./..."
	@./scripts/check-fmt.sh

lint: tools/bin/golangci-lint
	@echo "linting"
	@tools/bin/golangci-lint run

check: check-tidy check-fmt check-gogenerate lint
