# This file is part of Dependency-Track.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
# Copyright (c) OWASP Foundation. All Rights Reserved.

DEFAULT_BASE_REF := $(shell git rev-parse --verify --quiet upstream/main >/dev/null 2>&1 && echo upstream/main || echo origin/main)
BASE_REF ?= $(DEFAULT_BASE_REF)
BUF_FORMAT_FLAGS := --exclude-path support/cyclonedx-proto/src/main/proto/org/cyclonedx/v1_7/cyclonedx.proto
MIGRATION_DIR := migration/src/main/resources/org/dependencytrack/migration
DEX_MIGRATION_DIR := dex/engine-migration/src/main/resources/org/dependencytrack/dex/engine/migration
SPECTRAL_IMAGE := stoplight/spectral:6.16.3@sha256:a07aa4455367b9501b574423b684ab0ef3ee42556089013583318ec015249050
SQUAWK_IMAGE := ghcr.io/sbdchd/squawk:2.63.0@sha256:e3b8e534994ad714ec3ca1017f7e80ecb8f8a15b161b8c6eb25303eced5da3ab

MVN := $(shell command -v mvn 2>/dev/null)
MVND := $(shell command -v mvnd 2>/dev/null)
ifeq ($(MVND),)
	MVND := $(MVN)
endif
MVN_NO_BUILDCACHE := -Dmaven.build.cache.enabled=false

ifdef CI
	MVN_FLAGS := -B
else
	MVN_FLAGS :=
endif

ifdef AGENT
	MVN_FLAGS += -B -q -Dsurefire.useFile=false
endif

build:
	$(MVND) $(MVN_FLAGS) -Pquick package
.PHONY: build

build-dist:
	$(MVND) $(MVN_FLAGS) -Pdist,quick package
.PHONY: build-dist

build-image: build
	docker build \
		-t ghcr.io/dependencytrack/apiserver:local \
		-f apiserver/src/main/docker/Dockerfile \
		apiserver
.PHONY: build-image

build-v4-migrator-image: build
	docker build \
		-t ghcr.io/dependencytrack/v4-migrator:local \
		-f support/v4-migrator/src/main/docker/Dockerfile \
		support/v4-migrator
.PHONY: build-v4-migrator-image

datanucleus-enhance:
	$(MVND) $(MVN_FLAGS) \
		-Pquick \
		-Dresolve.skip \
		-pl alpine/alpine-model,apiserver \
		process-classes
.PHONY: datanucleus-enhance

install:
	$(MVND) $(MVN_FLAGS) -Pquick install
.PHONY: install

lint-java:
	$(MVND) $(MVN_FLAGS) $(MVN_NO_BUILDCACHE) -q validate
.PHONY: lint-java

format-java:
	$(MVND) $(MVN_FLAGS) $(MVN_NO_BUILDCACHE) -q spotless:apply
.PHONY: format-java

lint-migrations:
	@if ! git rev-parse --verify --quiet "$(BASE_REF)" >/dev/null; then \
		echo "BASE_REF '$(BASE_REF)' does not resolve to a git ref."; \
		echo "Override on the command line, e.g.: make lint-migrations BASE_REF=upstream/main"; \
		exit 1; \
	fi; \
	changed=$$( \
		{ \
			git diff --name-only --diff-filter=AM "$(BASE_REF)...HEAD" -- '$(MIGRATION_DIR)/*.sql'; \
			git diff --name-only --diff-filter=AM -- '$(MIGRATION_DIR)/*.sql'; \
			git ls-files --others --exclude-standard -- '$(MIGRATION_DIR)/*.sql'; \
		} | sort -u); \
	if [ -z "$$changed" ]; then \
		echo "No migration changes to lint in $(MIGRATION_DIR) (BASE_REF=$(BASE_REF))."; \
		exit 0; \
	fi; \
	echo "Linting migrations:"; \
	echo "$$changed" | sed 's/^/  /'; \
	docker run --rm -i \
		--platform linux/amd64 \
		-v "$(CURDIR):/work" \
		-w /work \
		$(SQUAWK_IMAGE) \
		lint $$changed
.PHONY: lint-migrations

lint-dex-migration:
	@$(MAKE) lint-migrations MIGRATION_DIR="$(DEX_MIGRATION_DIR)"
.PHONY: lint-dex-migration

lint-openapi:
	@dups=$$(find api/src/main/openapi -path '*/schemas/*.yaml' -exec basename {} \; \
		| sort | uniq -d); \
	if [ -n "$$dups" ]; then \
		echo "Duplicate schema basenames (must be globally unique):"; \
		echo "$$dups"; \
		exit 1; \
	fi
	docker run --rm -i -w /work \
		--platform linux/amd64 \
		-v "$(CURDIR)/api:/work" \
		$(SPECTRAL_IMAGE) lint \
		--ruleset src/main/spectral/ruleset.yaml \
		src/main/openapi/openapi.yaml
.PHONY: lint-openapi

lint-proto:
	buf lint
	buf format --diff --exit-code $(BUF_FORMAT_FLAGS)
.PHONY: lint-proto

format-proto:
	buf format --write $(BUF_FORMAT_FLAGS)
.PHONY: format-proto

lint: lint-java lint-migrations lint-dex-migration lint-openapi lint-proto
.PHONY: lint

test:
	$(MVND) $(MVN_FLAGS) -Dspotless.check.skip -Dcyclonedx.skip verify
.PHONY: test

test-single:
	$(MVND) $(MVN_FLAGS) test \
		$(MVN_NO_BUILDCACHE) \
		-Dspotless.check.skip \
		-Dcyclonedx.skip \
		-pl "$(MODULE)" \
		-am \
		-Dtest="$(TEST)"
.PHONY: test-single

new-migration:
	@if [ -z "$(NAME)" ]; then \
		echo "Usage: make new-migration NAME=\"short description\""; \
		exit 1; \
	fi; \
	slug=$$(printf '%s' "$(NAME)" | tr '[:upper:]' '[:lower:]' \
		| sed -e 's/[^a-z0-9]\{1,\}/_/g' -e 's/^_//' -e 's/_$$//'); \
	if [ -z "$$slug" ]; then \
		echo "NAME must contain at least one alphanumeric character"; \
		exit 1; \
	fi; \
	ts=$$(date -u +%Y%m%d%H%M); \
	dir="migration/src/main/resources/org/dependencytrack/migration"; \
	if ls "$$dir"/V$${ts}__*.sql >/dev/null 2>&1; then \
		echo "A migration with version $$ts already exists; wait a minute and retry"; \
		exit 1; \
	fi; \
	path="$$dir/V$${ts}__$${slug}.sql"; \
	: > "$$path"; \
	echo "$$path"
.PHONY: new-migration

apiserver-dev:
	$(MVN) $(MVN_FLAGS) -q -Pquick,dev-services -pl apiserver -am verify
.PHONY: apiserver-dev

apiserver-dev-remove-containers:
	@ids=$$(docker ps -aq --filter label=org.dependencytrack.dev-services); \
	if [ -n "$$ids" ]; then \
		docker rm -f $$ids; \
	else \
		echo "No dev services containers to remove"; \
	fi
.PHONY: apiserver-dev-remove-containers

test-e2e: build-image
	$(MVND) $(MVN_FLAGS) $(MVN_NO_BUILDCACHE) -pl e2e -am -DskipE2E=false verify
.PHONY: test-e2e

clean:
	$(MVND) $(MVN_FLAGS) $(MVN_NO_BUILDCACHE) -q clean
.PHONY: clean

clean-build-cache:
	rm -rf "$${HOME}"/.m2/build-cache/*/org.dependencytrack/
.PHONY: clean-build-cache

update-distro-info:
	curl -fsSL -o support/os-distro-metadata/src/main/resources/org/dependencytrack/support/distrometadata/debian.csv \
		https://debian.pages.debian.net/distro-info-data/debian.csv
	curl -fsSL -o support/os-distro-metadata/src/main/resources/org/dependencytrack/support/distrometadata/ubuntu.csv \
		https://debian.pages.debian.net/distro-info-data/ubuntu.csv
	curl -fsSL -o support/os-distro-metadata/src/main/resources/org/dependencytrack/support/distrometadata/LICENSE \
		https://salsa.debian.org/debian/distro-info-data/-/raw/main/debian/copyright
.PHONY: update-distro-info
