GO_BIN ?= go ## Allows overriding go executable.

TEST?=$$($(GO_BIN) list ./...)
GOFMT_FILES?=$$(find . -name '*.go')
WEBSITE_REPO=github.com/hashicorp/terraform-website
PKG_NAME=fastly
FULL_PKG_NAME=github.com/fastly/terraform-provider-fastly
VERSION_PLACEHOLDER=version.ProviderVersion
VERSION=$(shell git describe --tags --always)
VERSION_SHORT=$(shell git describe --tags --always --abbrev=0)
DOCS_PROVIDER_VERSION=$(subst v,,$(VERSION_SHORT))

# Enables support for tools such as https://github.com/rakyll/gotest
TEST_COMMAND ?= $(GO_BIN) test

# R019: ignore large number of arguments passed to HasChanges().
# R018: replace sleep with either resource.Retry() or WaitForState().
# R001: for complex d.Set() calls use a string literal instead.
TFPROVIDERLINT_DEFAULT_FLAGS=-R001=false -R018=false -R019=false -XR001=false

# XAT001: missing resource.TestCase ErrorCheck.
TFPROVIDERLINTX_DEFAULT_FLAGS=-XAT001=false

# Use a parallelism of 4 by default for tests, overriding whatever GOMAXPROCS is
# set to. For the acceptance tests especially, the main bottleneck affecting the
# tests is network bandwidth and Fastly API rate limits. Therefore using the
# system default value of GOMAXPROCS, which is usually determined by the number
# of processors available, doesn't make the most sense.
TEST_PARALLELISM?=4

# Tooling versions
GOLANGCI_LINT_VERSION = v2.4.0
BIN_DIR := $(CURDIR)/bin
GOLANGCI_LINT := $(BIN_DIR)/golangci-lint

default: build

build: clean
	$(GO_BIN) build -o bin/terraform-provider-$(PKG_NAME)_$(VERSION) -ldflags="-X $(FULL_PKG_NAME)/$(VERSION_PLACEHOLDER)=$(VERSION)"
	@sh -c "'$(CURDIR)/scripts/generate-dev-overrides.sh'"

test:
	$(TEST_COMMAND) $(TEST) || exit 1
	echo $(TEST) | \
		xargs -t -n4 $(TEST_COMMAND) $(TESTARGS) -timeout=30s -parallel=$(TEST_PARALLELISM)

# prefix `go test` with TF_LOG=debug or 'trace' for additional terraform output
# such as all the requests and responses it handles.
#
# reference:
# https://www.terraform.io/docs/internals/debugging.html
#
# TF_ACC is a recognised Terraform configuration that indicates we want to run an acceptance test, and which will result in creating REAL resources.
#
# reference:
# https://www.terraform.io/docs/extend/testing/acceptance-tests/index.html#running-acceptance-tests
#
testacc: lint tfproviderlintx fmt
	TF_ACC=1 $(TEST_COMMAND) $(TEST) -v $(TESTARGS) -parallel=$(TEST_PARALLELISM) -timeout 360m -ldflags="-X=$(FULL_PKG_NAME)/$(VERSION_PLACEHOLDER)=acc"

# WARNING: This target will delete infrastructure.
clean_test:
	@printf 'WARNING: This will delete infrastructure. Continue? (y/n) '; \
	read answer; \
	if echo "$$answer" | grep -iq '^y'; then \
	  SILENCE=true make sweep || true; \
		fastly service list --token $$FASTLY_API_KEY | grep -E '^tf\-' | awk '{print $$2}' | xargs -I % fastly service delete --token $$FASTLY_API_KEY -f -s %; \
		TEST_PARALLELISM=8 make testacc; \
	fi

fmt: install-linter check-linter-version
	@echo "==> Running golangci-lint --fix"
	@$(GOLANGCI_LINT) run --fix


test-compile:
	@if [ "$(TEST)" = "./..." ]; then \
		echo "ERROR: Set TEST to a specific package. For example,"; \
		echo "  make test-compile TEST=./$(PKG_NAME)"; \
		exit 1; \
	fi
	$(TEST_COMMAND) -c $(TEST) $(TESTARGS)

generate-docs:
	$(shell sed -e "s/__VERSION__/$(DOCS_PROVIDER_VERSION)/g" examples/index-fastly-provider.tf.tmpl > examples/index-fastly-provider.tf)
	$(GO_BIN) tool -modfile=tools/go.mod tfplugindocs generate
	rm examples/index-fastly-provider.tf

validate-docs:
	$(GO_BIN) tool -modfile=tools/go.mod tfplugindocs validate

tfproviderlintx:
	$(GO_BIN) tool -modfile=tools/go.mod tfproviderlintx $(TFPROVIDERLINT_DEFAULT_FLAGS) $(TFPROVIDERLINTX_DEFAULT_FLAGS) $(TFPROVIDERLINTX_ARGS) ./...

tfproviderlint:
	$(GO_BIN) tool -modfile=tools/go.mod tfproviderlint $(TFPROVIDERLINT_DEFAULT_FLAGS) $(TFPROVIDERLINT_ARGS) ./...

sweep:
	@if [ "$(SILENCE)" != "true" ]; then \
		echo "WARNING: This will destroy infrastructure. Use only in development accounts."; \
	fi
	$(TEST_COMMAND) ./fastly -v -sweep=ALL $(SWEEPARGS) -timeout 30m || true

clean:
	rm -rf ./bin

validate-interface:
	@./tests/interface/script.sh

lint: install-linter check-linter-version
	@echo "==> Running golangci-lint"
	@$(GOLANGCI_LINT) run --verbose

install-linter: ## Installs golangci-lint via go install
	@echo "==> Installing golangci-lint $(GOLANGCI_LINT_VERSION)"
	@mkdir -p $(BIN_DIR)
	@GOBIN=$(BIN_DIR) go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION)

check-linter-version: ## Verifies installed golangci-lint version matches expected
	@echo "==> Checking golangci-lint version"
	@EXPECTED="$(GOLANGCI_LINT_VERSION)"; \
	EXPECTED=$${EXPECTED#v}; \
	INSTALLED=$$($(GOLANGCI_LINT) version --short); \
	if [ "$$INSTALLED" != "$$EXPECTED" ]; then \
		echo "Expected golangci-lint v$$EXPECTED but found $$INSTALLED"; \
		exit 1; \
	fi

clean-bin: ## Removes locally installed binaries
	@echo "==> Cleaning ./bin directory"
	@rm -rf $(BIN_DIR)

.PHONY: all build clean clean_test default errcheck fmt fmtcheck generate-docs lint install-linter check-linter-version clean-bin sweep test test-compile testacc validate-docs validate-interface vet
