SHELL := /bin/bash
.DEFAULT_GOAL := help

include deployment.mk

CLOUD ?= aws
VALID_CLOUDS := aws gcp azure alicloud
TF_DIR := clouds/$(CLOUD)
STATE_KEY := date-integration-test-env/$(CLOUD)/terraform.tfstate
APPLY_FLAGS ?=

ifeq ($(filter $(CLOUD),$(VALID_CLOUDS)),)
$(error CLOUD must be one of: $(VALID_CLOUDS))
endif

TF_VARS_aws := \
	-var=target_account_id=$(AWS_ACCOUNT_ID) \
	-var=aws_profile=$(AWS_PROFILE) \
	-var=aws_region=$(AWS_REGION) \
	-var=instance_type=$(AWS_INSTANCE_TYPE) \
	-var=enable_pulsar=$(AWS_ENABLE_PULSAR) \
	-var=enable_schema_registry=$(AWS_ENABLE_SCHEMA_REGISTRY) \
	'-var=allowed_principal_arns=$(AWS_PRIVATELINK_ALLOWED_PRINCIPAL_ARNS)' \
	'-var=s3_backup_export_access_grants=$(AWS_S3_BACKUP_EXPORT_ACCESS_GRANTS)' \
	'-var=s3_assume_role_grants=$(AWS_S3_ASSUME_ROLE_GRANTS)'
TF_VARS_gcp := \
	-var=gcp_project_id=$(GCP_PROJECT_ID) \
	-var=gcp_region=$(GCP_REGION) \
	-var=gcp_zone=$(GCP_ZONE) \
	-var=machine_type=$(GCP_MACHINE_TYPE) \
	-var=enable_pulsar=$(GCP_ENABLE_PULSAR) \
	-var=enable_schema_registry=$(GCP_ENABLE_SCHEMA_REGISTRY) \
	'-var=private_service_connect_project_ids=$(GCP_PSC_CONSUMER_PROJECT_IDS)' \
	-var=gcs_e2e_runner_service_account=$(GCP_GCS_E2E_RUNNER_SERVICE_ACCOUNT) \
	'-var=gcs_backup_export_access_grants=$(GCP_GCS_BACKUP_EXPORT_ACCESS_GRANTS)' \
	'-var=gcs_cdc_access_grants=$(GCP_GCS_CDC_ACCESS_GRANTS)'
TF_VARS_azure := \
	-var=azure_subscription_id=$(AZURE_SUBSCRIPTION_ID) \
	-var=azure_subscription_name=$(AZURE_SUBSCRIPTION_NAME) \
	-var=azure_location=$(AZURE_LOCATION) \
	-var=kafka_privatelink_availability_zone=$(AZURE_KAFKA_PRIVATELINK_AVAILABILITY_ZONE) \
	-var=vm_size=$(AZURE_VM_SIZE) \
	-var=enable_pulsar=$(AZURE_ENABLE_PULSAR) \
	-var=enable_schema_registry=$(AZURE_ENABLE_SCHEMA_REGISTRY) \
	-var=blob_sas_expiry=$(AZURE_BLOB_SAS_EXPIRY) \
	'-var=private_link_subscription_ids=$(AZURE_PRIVATELINK_SUBSCRIPTION_IDS)'
TF_VARS_alicloud := \
	-var=target_account_id=$(ALICLOUD_ACCOUNT_ID) \
	-var=target_account_name=$(ALICLOUD_ACCOUNT_NAME) \
	-var=alicloud_profile=$(ALICLOUD_PROFILE) \
	-var=alicloud_region=$(ALICLOUD_REGION) \
	-var=instance_type=$(ALICLOUD_INSTANCE_TYPE) \
	-var=enable_pulsar=$(ALICLOUD_ENABLE_PULSAR) \
	-var=enable_schema_registry=$(ALICLOUD_ENABLE_SCHEMA_REGISTRY) \
	'-var=privatelink_allowed_account_ids=$(ALICLOUD_PRIVATELINK_ACCOUNT_IDS)'
TF_VARS := $(TF_VARS_$(CLOUD))
TF_ENV_gcp := GOOGLE_OAUTH_ACCESS_TOKEN="$$(gcloud auth print-access-token)"
TF_ENV := $(TF_ENV_$(CLOUD))

.PHONY: help state-bucket init ensure-backend fmt validate validate-all test plan up wake sleep sleep-deep smoke smoke-storage seed-import audit-tags outputs e2e-config sync-e2e-config destroy

help:
	@echo 'Use CLOUD=aws|gcp|azure|alicloud; defaults to aws.'
	@echo 'Targets: init validate validate-all plan up wake sleep sleep-deep smoke smoke-storage seed-import audit-tags outputs e2e-config sync-e2e-config destroy'

state-bucket:
	AWS_PROFILE=$(AWS_PROFILE) STATE_REGION=$(STATE_REGION) STATE_BUCKET=$(STATE_BUCKET) ./scripts/bootstrap-state-bucket.sh

init: state-bucket
	umask 077; terraform -chdir=$(TF_DIR) init -reconfigure \
		-backend-config=bucket=$(STATE_BUCKET) \
		-backend-config=key=$(STATE_KEY) \
		-backend-config=region=$(STATE_REGION) \
		-backend-config=profile=$(AWS_PROFILE) \
		-backend-config=use_lockfile=$(STATE_USE_LOCKFILE) \
		-input=false

ensure-backend:
	@if TF_MODULE_DIR=$(TF_DIR) \
		STATE_BUCKET=$(STATE_BUCKET) \
		STATE_KEY=$(STATE_KEY) \
		STATE_REGION=$(STATE_REGION) \
		AWS_PROFILE=$(AWS_PROFILE) \
		STATE_USE_LOCKFILE=$(STATE_USE_LOCKFILE) \
		./scripts/terraform-backend-is-current.sh; then \
		echo 'Terraform backend is already initialized for $(CLOUD).'; \
	else \
		echo 'Terraform backend is missing or stale for $(CLOUD); running init.'; \
		$(MAKE) init CLOUD=$(CLOUD); \
	fi

fmt:
	terraform fmt -recursive .

validate: init
	terraform fmt -check -recursive .
	terraform -chdir=$(TF_DIR) validate
	python3 -m py_compile scripts/create_pulsar_token.py
	for script in scripts/*.sh clouds/*/*.sh; do bash -n "$$script"; done

validate-all:
	set -e; for cloud_name in $(VALID_CLOUDS); do $(MAKE) validate CLOUD=$$cloud_name; done

test: validate
	terraform -chdir=$(TF_DIR) test $(TF_VARS)

plan: init
	umask 077; $(TF_ENV) terraform -chdir=$(TF_DIR) plan $(TF_VARS) -out=date-integration.tfplan

up wake: init
	umask 077; $(TF_ENV) terraform -chdir=$(TF_DIR) apply $(APPLY_FLAGS) $(TF_VARS) -var=desired_state=running
	$(MAKE) smoke CLOUD=$(CLOUD)

sleep: init
	umask 077; $(TF_ENV) terraform -chdir=$(TF_DIR) apply $(APPLY_FLAGS) $(TF_VARS) \
		-var=desired_state=stopped -var=remove_privatelink_when_stopped=false

sleep-deep: init
	@if [[ "$(CLOUD)" == aws ]]; then \
		TF_MODULE_DIR=$(CURDIR)/$(TF_DIR) AWS_PROFILE=$(AWS_PROFILE) AWS_REGION=$(AWS_REGION) ./scripts/check-privatelink-connections.sh; \
	elif [[ "$(CLOUD)" == gcp ]]; then \
		(cd $(TF_DIR) && ./check-psc-connections.sh); \
	elif [[ "$(CLOUD)" == alicloud ]]; then \
		(cd $(TF_DIR) && ALICLOUD_PROFILE=$(ALICLOUD_PROFILE) ALICLOUD_REGION=$(ALICLOUD_REGION) ./check-private-endpoint-connections.sh); \
	else \
		(cd $(TF_DIR) && ./check-private-endpoint-connections.sh); \
	fi
	umask 077; $(TF_ENV) terraform -chdir=$(TF_DIR) apply $(APPLY_FLAGS) $(TF_VARS) \
		-var=desired_state=stopped -var=remove_privatelink_when_stopped=true

smoke: init
	TF_MODULE_DIR=$(CURDIR)/$(TF_DIR) CLOUD=$(CLOUD) \
		GCP_PROJECT_ID=$(GCP_PROJECT_ID) GCP_ZONE=$(GCP_ZONE) \
		AZURE_SUBSCRIPTION_ID=$(AZURE_SUBSCRIPTION_ID) \
		ALICLOUD_PROFILE=$(ALICLOUD_PROFILE) ALICLOUD_REGION=$(ALICLOUD_REGION) ./scripts/smoke-cloud.sh

smoke-storage: init
	@if [[ "$(CLOUD)" == aws ]]; then \
		TF_MODULE_DIR=$(CURDIR)/$(TF_DIR) ./scripts/smoke-s3.sh; \
	elif [[ "$(CLOUD)" == azure ]]; then \
		TF_MODULE_DIR=$(CURDIR)/$(TF_DIR) ./scripts/smoke-azure-storage.sh; \
	elif [[ "$(CLOUD)" == alicloud ]]; then \
		TF_MODULE_DIR=$(CURDIR)/$(TF_DIR) ALICLOUD_PROFILE=$(ALICLOUD_PROFILE) \
			ALICLOUD_REGION=$(ALICLOUD_REGION) ./scripts/smoke-alicloud-oss.sh; \
	else \
		echo 'Storage smoke is not required for GCP because it uses VM service-account IAM.'; \
	fi

audit-tags: init
	@if [[ "$(CLOUD)" == aws ]]; then \
		TF_MODULE_DIR=$(CURDIR)/$(TF_DIR) ./scripts/check-audit-tags.sh; \
	elif [[ "$(CLOUD)" == alicloud ]]; then \
		TF_MODULE_DIR=$(CURDIR)/$(TF_DIR) ./scripts/check-alicloud-audit-tags.sh; \
	else \
		echo 'Review provider-native labels/tags in plan for $(CLOUD).'; \
	fi

# Seed self-managed import sample data for the clouds that own a disposable
# import bucket/container (Alibaba Cloud OSS for premium import, Azure Blob for
# dedicated import). AWS/GCP import sample data comes from public reference
# buckets and needs no seeding.
seed-import: init
	@if [[ "$(CLOUD)" == alicloud ]]; then \
		TF_MODULE_DIR=$(CURDIR)/$(TF_DIR) ALICLOUD_PROFILE=$(ALICLOUD_PROFILE) \
			ALICLOUD_REGION=$(ALICLOUD_REGION) ./scripts/seed-alicloud-oss-import.sh; \
	elif [[ "$(CLOUD)" == azure ]]; then \
		TF_MODULE_DIR=$(CURDIR)/$(TF_DIR) ./scripts/seed-azure-blob-import.sh; \
	else \
		echo 'Import sample data for $(CLOUD) is provided by public reference buckets; nothing to seed.'; \
	fi

outputs: ensure-backend
	terraform -chdir=$(TF_DIR) output

e2e-config: ensure-backend
	terraform -chdir=$(TF_DIR) output -raw e2e_dependency_yaml

sync-e2e-config:
	set -e; for cloud_name in $(VALID_CLOUDS); do $(MAKE) ensure-backend CLOUD=$$cloud_name >/dev/null; done
	cd ../../e2e && go run ./script/sync_test_server_config.go

destroy: init
	umask 077; $(TF_ENV) terraform -chdir=$(TF_DIR) destroy $(APPLY_FLAGS) $(TF_VARS)
