DEVP_LINT_GOGC := $(if $(DEVP_LINT_GOGC),$(DEVP_LINT_GOGC),100)
DEVP_LINT_ARGS := $(if $(DEVP_LINT_ARGS),$(DEVP_LINT_ARGS),)

.PHONY: devp/lint-go
devp/lint-go: ${DEVP_GOLANG_CI_LINT_EXE}
	@# Run linter with local config
	$(Q) GOGC=${DEVP_LINT_GOGC} ${DEVP_GOLANG_CI_LINT_EXE} -v run ./...

.PHONY: devp/lint-go-fix
devp/lint-go-fix: ${DEVP_GOLANG_CI_LINT_EXE}
	@# Run linter with local config and --fix flag
	$(Q) GOGC=${DEVP_LINT_GOGC} ${DEVP_GOLANG_CI_LINT_EXE} -v run ./... --fix

.PHONY: devp/lint-go/vscode-enable
devp/lint-go/vscode-enable: ${DEVP_DEVPTOOL_EXE} ${DEVP_LINT_EXE}
	@# Enable platform linting in VS Code
	$(Q) ${DEVP_DEVPTOOL_EXE} golang configure-ide vscode linter --devplint-path=${DEVP_LINT_EXE} --golangci-lint-path=${DEVP_GOLANG_CI_LINT_EXE}

.PHONY: devp/lint-go/vscode-disable
devp/lint-go/vscode-disable: ${DEVP_DEVPTOOL_EXE} ${DEVP_GOLANG_CI_LINT_EXE} ${DEVP_LINT_EXE}
	@# Disable platform linting in VS Code
	$(Q) ${DEVP_DEVPTOOL_EXE} golang configure-ide vscode linter --devplint-path=${DEVP_LINT_EXE} --golangci-lint-path=${DEVP_GOLANG_CI_LINT_EXE} --enable=false

.PHONY: devp/lint-go/goland-enable
devp/lint-go/goland-enable: ${DEVP_DEVPTOOL_EXE} ${DEVP_GOLANG_CI_LINT_EXE} ${DEVP_LINT_EXE}
	@# Enable platform linting in Goland
	$(Q) ${DEVP_DEVPTOOL_EXE} golang configure-ide goland linter --devplint-path=${DEVP_LINT_EXE} --golangci-lint-path=${DEVP_GOLANG_CI_LINT_EXE}

.PHONY: devp/lint-go/goland-disable
devp/lint-go/goland-disable: ${DEVP_DEVPTOOL_EXE} ${DEVP_GOLANG_CI_LINT_EXE} ${DEVP_LINT_EXE}
	@# Disable platform linting in Goland
	$(Q) ${DEVP_DEVPTOOL_EXE} golang configure-ide goland linter --devplint-path=${DEVP_LINT_EXE} --golangci-lint-path=${DEVP_GOLANG_CI_LINT_EXE} --enable=false

DEVP_LINT_SCRIPTS_ROOT := $(if $(DEVP_LINT_SCRIPTS_ROOT),$(DEVP_LINT_SCRIPTS_ROOT),.)
DEVP_LINT_DEFAULT_PATH = ${DEVP_SCRIPTS}/lint/golangci.yml
DEVP_LINT_FIX_PATH := ${DEVP_LINT_SCRIPTS_ROOT}/scripts/golangci-fix.yml
DEVP_LINT_MERGED_PATH := ${DEVP_LINT_SCRIPTS_ROOT}/scripts/golangci-merged.yml

# If 'scripts/golangci-fix.yml' file exists, we need to merge it with the default config
# Otherwise we just use the default config directly
ifeq ($(wildcard ${DEVP_LINT_FIX_PATH}),)
DEVP_LINT_CONFIG_PATH = ${DEVP_LINT_DEFAULT_PATH}
DEVP_LINT_FIX = 0
else
DEVP_LINT_CONFIG_PATH = ${DEVP_LINT_MERGED_PATH}
DEVP_LINT_FIX = 1
endif

DEVP_GOLANG_CI_LINT_CMD := ${DEVP_GOLANG_CI_LINT_EXE} -v --config ${DEVP_LINT_CONFIG_PATH} ${DEVP_LINT_ARGS} run

.PHONY: devp/lint-clean-config
devp/lint-clean-config:
	@# Remove merged config if 'scripts/golangci-fix.yml' doesn't exist
ifeq ($(DEVP_LINT_FIX), 0)
	$(Q) rm -f ${DEVP_LINT_MERGED_PATH}
endif

${DEVP_LINT_MERGED_PATH}: ${DEVP_YQ_EXE} ${DEVP_LINT_DEFAULT_PATH} $(wildcard ${DEVP_LINT_FIX_PATH})
	@# Config file merged from the default platform config and 'scripts/golangci-fix.yml'
	$(Q) echo "Generating merged config into '${@}'"
	$(Q) ${DEVP_SCRIPTS}/lint/merge-lint-config.sh $@ $^

.PHONY: devp/lint-config-verify
devp/lint-config-verify:
	@# Verify linting config
	$(Q) echo "Verifying linting config"
	$(Q) ${DEVP_GOLANG_CI_LINT_EXE} config verify --config ${DEVP_LINT_CONFIG_PATH}

.PHONY: devp/lint-deps
devp/lint-deps: devp/lint-clean-config ${DEVP_GOLANG_CI_LINT_EXE} ${DEVP_LINT_CONFIG_PATH}
	@# Prepare linter config, install golangci-lint if needed and call `devp/lint-config-verify` if `golangci-fix.yml`exists
ifeq ($(DEVP_LINT_FIX), 1)
	$(Q) $(MAKE) devp/lint-config-verify
endif

.PHONY: devp/lint-go-default
devp/lint-go-default: devp/lint-deps
	@# Run linter with the platform config
	$(Q) GOGC=${DEVP_LINT_GOGC} ${DEVP_GOLANG_CI_LINT_CMD} ./...

.PHONY: devp/lint-go-default-report
devp/lint-go-default-report: devp/lint-deps
	@# Generate linting json report for the platform linting config
	$(Q) GOGC=${DEVP_LINT_GOGC} ${DEVP_GOLANG_CI_LINT_CMD} --output.json.path=devp_lint_report.json

.PHONY: devp/lint-go-default-fix
devp/lint-go-default-fix: devp/lint-deps
	@# Run linter with the platform config and --fix flag
	$(Q) GOGC=${DEVP_LINT_GOGC} ${DEVP_GOLANG_CI_LINT_CMD} ./... --fix

.PHONY: devp/lint-cache-clean
devp/lint-cache-clean: ${DEVP_GOLANG_CI_LINT_EXE}
	@# Clean linter cache
	$(Q) ${DEVP_GOLANG_CI_LINT_EXE} cache clean

.PHONY: devp/lint-cache-status
devp/lint-cache-status: ${DEVP_GOLANG_CI_LINT_EXE}
	@# Show cache directory path and size
	$(Q) ${DEVP_GOLANG_CI_LINT_EXE} cache status

.PHONY: .devp/lint-go-nolint-gen
.devp/lint-go-nolint-gen: ${DEVP_DEVPTOOL_EXE}
	@# [For Devp team. Do not call directly.] Generate 'nolint' directives for all linting issues.
	$(Q) ${DEVP_DEVPTOOL_EXE} golang lint nolint-gen
