
GO     := GO111MODULE=on go
# Default value for CGO_ENABLED is 0
CGO_ENABLED_DEFAULT := 1

# Detect the current operating system
ifeq ($(shell uname -s),Darwin)
    # If it's macOS, set CGO_ENABLED to 1, because gosigar requires cgo on macOS
    CGO_ENABLED := 1
else
    # If it's not macOS, use the default value
    CGO_ENABLED := $(CGO_ENABLED_DEFAULT)
    LDFLAGS += -s -w -extldflags "-static"
endif

GOBUILD := CGO_ENABLED=$(CGO_ENABLED) $(GO) build
GOTEST := CGO_ENABLED=1 $(GO) test -p 3 --race
LDFLAGS += -X "github.com/tidbcloud/serverless-service/pkg/version.GitHash=$(shell git rev-parse HEAD)"
LDFLAGS += -X "github.com/tidbcloud/serverless-service/pkg/version.GitBranch=$(shell git rev-parse --abbrev-ref HEAD)"
FILES := $$(find . -name '*.go' -type f | grep -vE 'proto|pb\.go|pb\.gw\.go')
PROTO_FILES := $$(find ./idl/idl/v1beta1 -name '*.proto' -type f)
FAIL_ON_STDOUT := awk '{ print } END { if (NR > 0) { exit 1  }  }'
COVERAGE_OUT := coverage.out
ARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))

.PHONY: build
build: build-server

.PHONY: build-server
build-server:
	$(GOBUILD) -ldflags '$(LDFLAGS)' -o bin/server cmd/server/main.go

.PHONY: check
check: lint fmt
	@git --no-pager diff --exit-code || echo "Please add changed files!"

.PHONY: lint
lint: lint-idl lint-golang

.PHONY: lint-idl
lint-idl: tools/bin/buf
	cd idl/idl && ../../tools/bin/buf lint

.PHONY: lint-golang
lint-golang: tools/bin/golangci-lint
	tools/bin/golangci-lint run --timeout 10m --verbose

.PHONY: lint-golang-fix
lint-golang-fix: tools/bin/golangci-lint
	tools/bin/golangci-lint run --fix --timeout 10m --verbose

.PHONY: lint-api
lint-api: tools/bin/api-linter generate-buf-exps
	tools/bin/api-linter --config idl/idl/api-linter.yaml --set-exit-status -I idl/exps $(PROTO_FILES)

.PHONY: lint-typescript
lint-typescript:
	npm run check --prefix deployments/pulumi
	npm run lint --prefix deployments/pulumi

.PHONY: fmt
fmt: fmt-idl fmt-golang

.PHONY: fmt-idl
fmt-idl: tools/bin/buf
	tools/bin/buf format -w --exit-code idl/idl/

.PHONY: fmt-golang
fmt-golang: tools/bin/golangci-lint tools/bin/gofumpt
	@echo "golangci-lint run --fix"
	tools/bin/golangci-lint run --fix
	@echo "gofmt (simplify)"
	tools/bin/gofumpt -l -w $(FILES) 2>&1 | $(FAIL_ON_STDOUT)

.PHONY: fmt-golang-ci
fmt-golang-ci: tools/bin/gofumpt
	tools/bin/gofumpt -d -l -e $(FILES) | $(FAIL_ON_STDOUT)

.PHONY: fmt-typescript
fmt-typescript:
	npm run fmt --prefix deployments/pulumi

.PHONY: test
test: tools/bin/gotestsum
	CGO_ENABLED=1 tools/bin/gotestsum -- --race -v -count=1 -cover -coverprofile=$(COVERAGE_OUT) ./...

.PHONY: coverage
coverage: test
	gcov2lcov -infile=coverage.out -outfile=coverage.lcov
	genhtml -o coverage_html coverage.lcov

.PHONY: generate
generate: generate-idl generate-mock generate-k8s-api

.PHONY: generate-idl
generate-idl: tools/bin/buf
	@echo "generate idl code"
	cd idl/idl && $(shell pwd)/tools/bin/buf dep update
	cd idl/idl && $(shell pwd)/tools/bin/buf generate -v --exclude-path ./v1beta1
	cd idl/idl && $(shell pwd)/tools/bin/buf generate -v --path ./v1beta1 --template ./v1beta1/buf.gen.yaml
	rm idl/pbgen/proto/rpc/*.swagger.json
	rm idl/pbgen/proto/common/*.swagger.json
	mv idl/pbgen/proto/console/*.swagger.json apidocs/console/
	mv idl/pbgen/proto/serverless/*.swagger.json apidocs/console/
	mv idl/pbgen/proto/v1beta/*.swagger.json apidocs/v1beta/
	mv idl/pbgen/proto/v1beta1/*.swagger.json apidocs/v1beta1/

	@for f in $$(find apidocs -name "*.json"); do \
		echo $$f; \
		scripts/postbuf.py $$f; \
		npx @openapitools/openapi-generator-cli validate --openapitools idl/idl/openapitools.json -i $$f; \
	done

.PHONY: generate-mock
generate-mock: tools/bin/mockgen
	@echo "generate mock code"
	./scripts/gen_mock.sh $(shell pwd)/tools/bin/mockgen

.PHONY: generate-buf-exps
generate-buf-exps: tools/bin/buf
	tools/bin/buf export idl/idl --output idl/exps

.PHONY: generate-k8s-api
generate-k8s-api: tools/bin/controller-gen tools/bin/crd2pulumi
	@echo "generate k8s api code"
	tools/bin/controller-gen object:headerFile=./scripts/boilerplate.go.txt paths="./k8sapi/..."
	tools/bin/controller-gen crd:allowDangerousTypes=true paths="./k8sapi/..." output:crd:artifacts:config="./deployments/pulumi/manifests/crd"
	tools/bin/crd2pulumi --force --nodejsPath deployments/pulumi/src/crd ./deployments/pulumi/manifests/crd/*.yaml

.PHONY: clean
clean: clean-idl clean-server

.PHONY: clean-idl
clean-idl:
	rm -r idl/pbgen/proto
	rm -r apidocs/console/*
	rm -r apidocs/v1beta/*
	rm -r apidocs/v1beta1/*

.PHONY: clean-server
clean-server:
	rm bin/server

.PHONY: purge
purge: clean
	rm -r tools/bin

.PHONY: local-run
local-run: build
	./scripts/run_local.sh $(ARGS)

# tools
tools/bin/gotestsum: tools/go.mod
	make -C ./tools gotestsum

tools/bin/golangci-lint: tools/go.mod
	make -C ./tools golangci-lint

tools/bin/gofumpt: tools/go.mod
	make -C ./tools gofumpt

tools/bin/buf:
	make -C ./tools buf

tools/bin/mockgen:
	make -C ./tools mockgen

tools/bin/api-linter:
	make -C ./tools api-linter

tools/bin/controller-gen:
	make -C ./tools controller-gen

tools/bin/crd2pulumi:
	make -C ./tools crd2pulumi
