WEBAPP_DIR      = "./webapp"
AUTO_DOC_DIR    = "documentation/auto-generated-documentation"
AUTO_DOC_ROUTES_DIR = "./$(AUTO_DOC_DIR)/webapp_routes"
AUTO_DOC_PHPUNIT_DIR = "../../$(AUTO_DOC_DIR)/tests_phpunit"
AUTO_DOC_PSALM_DIR = "../../$(AUTO_DOC_DIR)/php_static-analysis_psalm"
AUTO_DOC_PHPMD_DIR = "./$(AUTO_DOC_DIR)/php_static-analysis_phpmd"
AUTO_DOC_SBOM_DIR = "./$(AUTO_DOC_DIR)/sbom"
AUTO_DOC_SECURITY_DIR = "./$(AUTO_DOC_DIR)/security"
INFECTION_PHPUNIT_OPTION = "--group=allow_mutation_testing_by_infection"

DOCKER_COMPOSE	= $(WEBAPP_DIR)/docker-compose
CONSOLE			= $(WEBAPP_DIR)/bin/console
PHPUNIT			= $(WEBAPP_DIR)/bin/phpunit

##
##--- SYMFONY Routes ----------------------------------------------------------

verif_autodoc_routes: ## Check that Symfony route auto-documentation files are up to date
	$(CONSOLE) debug:route --env=prod --format=json --show-controllers > $(AUTO_DOC_ROUTES_DIR)/webapp_routes_prod.json
	$(CONSOLE) debug:route --env=prod --format=md   --show-controllers > $(AUTO_DOC_ROUTES_DIR)/webapp_routes_prod.md
	$(CONSOLE) debug:route --env=prod --format=txt  --show-controllers --no-ansi > $(AUTO_DOC_ROUTES_DIR)/webapp_routes_prod.txt
	git diff  --name-only
	cat $(AUTO_DOC_ROUTES_DIR)/webapp_routes_prod.txt;
	@if [ `git diff  --name-only | grep "webapp_routes_prod." | wc -l` -gt 0 ]; then \
		echo ""; \
		git diff --no-color $(AUTO_DOC_ROUTES_DIR)/webapp_routes_prod.txt ; \
		echo "----> ERROR: auto-generated documentation is not up-to-date ---> webapp_routes"; \
		echo "             fix it with folling command line: "; \
		echo "                          make autodoc_routes"; \
		echo ""; \
		exit 1;	 \
	fi;
#	fi; > /dev/null 2>&1
.PHONY: verif_autodoc_routes

autodoc_routes: ## Generating Symfony route auto-documentation files
#	$(CONSOLE) debug:route --env=dev  --format=json --show-controllers > webapp_routes_dev.json
#	$(CONSOLE) debug:route --env=dev  --format=md   --show-controllers > webapp_routes_dev.md
#	$(CONSOLE) debug:route --env=dev  --format=txt  --show-controllers > webapp_routes_dev.txt
	$(CONSOLE) debug:route --env=prod --format=json --show-controllers > $(AUTO_DOC_ROUTES_DIR)/webapp_routes_prod.json
	$(CONSOLE) debug:route --env=prod --format=md   --show-controllers > $(AUTO_DOC_ROUTES_DIR)/webapp_routes_prod.md
	$(CONSOLE) debug:route --env=prod --format=txt  --show-controllers --no-ansi > $(AUTO_DOC_ROUTES_DIR)/webapp_routes_prod.txt
	$(CONSOLE) debug:route --env=prod --format=txt  --show-controllers
.PHONY: autodoc_routes

routes: ## Display Symfony routes
	$(CONSOLE) debug:route --env=prod --format=txt  --show-controllers
.PHONY: routes



##
##--- GITLAB CI - Prepare prerequisites ------------------------------------------------------------------

dev_prepare_ci_build_all_images: ## Build all images used by Gitlab CI
	cd .gitlab/ci/Dockerfiles && ./10_build_all-images.sh
.PHONY: dev_prepare_ci_build_all_images

dev_prepare_ci_push_all_images: ## Push all images used by Gitlab CI
	cd .gitlab/ci/Dockerfiles && ./30_push_all-images.sh
.PHONY: ci_prerequisites_push_all_images

gitlab_api_login: ## Login to Gitlab API
	cd .gitlab/ci/Dockerfiles && ./80_gitlab-login.sh
.PHONY: gitlab_api_logout

gitlab_api_logout: ## Logout to Gitlab API
	cd .gitlab/ci/Dockerfiles && ./90_gitlab-logout.sh
.PHONY: gitlab_api_logout

##
##--- DOCKER ------------------------------------------------------------------

docker: ## Run Docker containers (database, mailcatcher)
	cd "${WEBAPP_DIR}/docker" && docker-compose up
.PHONY: docker

docker_clean_database: ## Clean up Docker containers (database, mailcatcher)
	cd "${WEBAPP_DIR}/docker" && docker compose down --volumes
	cd "${WEBAPP_DIR}/docker" && docker compose rm   --force --stop --volumes
.PHONY: docker_clean_database

docker_with_empty-database: ## Run Docker containers (database, mailcatcher)  with empty database
	cd "${WEBAPP_DIR}/docker" && docker compose down --volumes
	cd "${WEBAPP_DIR}/docker" && docker compose rm   --force --stop --volumes
	cd "${WEBAPP_DIR}/docker" && docker-compose up
.PHONY: docker_with_empty-database

##
##--- DEV environment --------------------------------------------------------

migration_database_env_dev: ## Apply Doctrine migrations (DEV environment)
	cd "${WEBAPP_DIR}"        && bin/console doctrine:migrations:list       --env=dev
	cd "${WEBAPP_DIR}"        && bin/console doctrine:migrations:migrate -n --env=dev
	cd "${WEBAPP_DIR}"        && bin/console doctrine:migrations:list       --env=dev
.PHONY: migration_database_env_dev

load_fixture_env_dev: ## Clean up database and load fixture (DEV environment)
	rm -rf "${WEBAPP_DIR}/public/images/content/organization"
	rm -rf "${WEBAPP_DIR}/public/images/content/software"
	cp -r  "${WEBAPP_DIR}/src/DataFixtures/images/organization" "${WEBAPP_DIR}/public/images/content/"
	cp -r  "${WEBAPP_DIR}/src/DataFixtures/images/software"     "${WEBAPP_DIR}/public/images/content/"
	cd "${WEBAPP_DIR}" && bin/console doctrine:database:drop --force --env=dev || true
	cd "${WEBAPP_DIR}" && bin/console doctrine:database:create       --env=dev
	cd "${WEBAPP_DIR}" && bin/console doctrine:migrations:migrate -n --env=dev
	cd "${WEBAPP_DIR}" && bin/console doctrine:fixtures:load      -n --env=dev
.PHONY: load_fixture_env_dev


##
##--- TESTS -------------------------------------------------------------------
tests: ## Run all tests (PhpUnit)
	rm -rvf "${WEBAPP_DIR}/var/tmp/" || true
	cd "${WEBAPP_DIR}" && bin/console doctrine:database:drop --force --env=test || true
	cd "${WEBAPP_DIR}" && bin/console doctrine:database:create       --env=test
	cd "${WEBAPP_DIR}" && bin/console doctrine:migrations:migrate -n --env=test
	cd "${WEBAPP_DIR}" && bin/console doctrine:fixtures:load      -n --env=test
	cd "${WEBAPP_DIR}" &&  XDEBUG_MODE=coverage bin/phpunit --testdox --strict-coverage --configuration phpunit.xml.dist
# 	cd "${WEBAPP_DIR}" &&  bin/phpunit --no-coverage --configuration phpunit.xml.dist
# 	cd "${WEBAPP_DIR}" &&  bin/phpunit --coverage-text --configuration phpunit.xml
.PHONY: tests

tests_gogogo: ## Run "gogogo" group tests (PhpUnit)
	rm -rvf "${WEBAPP_DIR}/var/tmp/" || true
	cd "${WEBAPP_DIR}" && bin/console doctrine:database:drop --force --env=test || true
	cd "${WEBAPP_DIR}" && bin/console doctrine:database:create       --env=test
	cd "${WEBAPP_DIR}" && bin/console doctrine:migrations:migrate -n --env=test
	cd "${WEBAPP_DIR}" && bin/console doctrine:fixtures:load      -n --env=test
	cd "${WEBAPP_DIR}" && bin/phpunit --testdox --group gogogo --configuration phpunit.xml.dist
# 	cd "${WEBAPP_DIR}" &&  bin/phpunit --no-coverage --configuration phpunit.xml.dist
# 	cd "${WEBAPP_DIR}" &&  bin/phpunit --coverage-text --configuration phpunit.xml
.PHONY: tests_gogogo

tests_coverage: ## Run all tests (PhpUnit) and save coverage in an HTML file
	rm -rvf "${WEBAPP_DIR}/var/tmp/" || true
	cd "${WEBAPP_DIR}" && \
	XDEBUG_MODE=coverage \
	bin/phpunit  --configuration phpunit.xml.dist --testdox --strict-coverage --coverage-text  --coverage-html "${AUTO_DOC_PHPUNIT_DIR}"
.PHONY: tests_coverage

tests_mutation: ## Run mutation tests (Infection)   TODO replace PHIVE by COMPOSER
	rm -rf "${WEBAPP_DIR}/var/tmp/" || true
	cd "${WEBAPP_DIR}" && ../bin/infection --min-covered-msi=95 --min-msi=15 --test-framework-options="${INFECTION_PHPUNIT_OPTION}"
#	cd "${WEBAPP_DIR}" && ../bin/infection --logger-html="${AUTO_DOC_INFECTION_FILE}" --test-framework-options="${INFECTION_PHPUNIT_OPTION}"
.PHONY: tests_mutation

tests_repeat: ## Run all tests (PhpUnit) multiple times
	rm -rvf "${WEBAPP_DIR}/var/tmp/" || true
	cd "${WEBAPP_DIR}" &&  bin/phpunit --testdox --no-coverage --configuration phpunit.xml.dist --repeat 10
.PHONY: tests_repeat


##
##--- CODING STANDART ---------------------------------------------------------
sf_coding-standard: ## ...
	bin/php-cs-fixer fix -vvv --diff --dry-run webapp/src/
	bin/php-cs-fixer fix -vvv --diff --dry-run webapp/tests/
.PHONY: sf_coding-standard

sf_fix-coding-standard: ## ...
	bin/php-cs-fixer fix -vvv --diff  webapp/src/
	bin/php-cs-fixer fix -vvv --diff  webapp/tests/
.PHONY: sf_fix-coding-standard


twig_linter: ## Twig templates linter
	webapp/bin/console lint:twig --show-deprecations webapp/templates/
.PHONY: twig_linter

php_coding-standard: ## PHP coding standards, via PHPCS (PHP Code Sniffer)
	bin/phpcs --standard=PSR12 --colors  webapp/src/ webapp/tests/ -s
.PHONY: php_coding-standard

php_coding-standard_diff: ## PHP coding standards, via PHPCS (PHP Code Sniffer) + display DIFF
	bin/phpcs --standard=PSR12 --colors  webapp/src/ webapp/tests/ --report=diff
.PHONY: php_coding-standard_diff

php_coding-standard_summary: ## PHP coding standards, via PHPCS (PHP Code Sniffer), with summary report
	bin/phpcs --standard=PSR12 --colors  webapp/src/ webapp/tests/ --report=summary
.PHONY: php_coding-standard_summary


php_fix-coding-standard: ## ...
	bin/phpcbf --standard=PSR12 --colors  webapp/src/ webapp/tests/
.PHONY: php_fix-coding-standard

##
##--- OTHER -------------------------------------------------------------------
php_linter: ## PHP Linter
	bin/parallel-lint --colors webapp/ --exclude webapp/vendor/ --exclude webapp/var/
.PHONY: php_linter


analyse_php_psalm: ## ...
	bin/psalm --root  webapp/ 					--report="${AUTO_DOC_PSALM_DIR}/Psalm_report.console" \
								  					--report="${AUTO_DOC_PSALM_DIR}/Psalm_report.txt"
.PHONY: analyse_php_psalm

analyse_php_psalm_show-info: ## ...
	bin/psalm --root  webapp/ --show-info=true  --report="${AUTO_DOC_PSALM_DIR}/Psalm_report.console" \
                                                    --report="${AUTO_DOC_PSALM_DIR}/Psalm_report.txt"
.PHONY: analyse_php_psalm_show-info

analyse_php_stan: ## ...
	bin/phpstan analyse --level=0 webapp/src/
	bin/phpstan analyse --level=0 webapp/tests/
.PHONY: analyse_php_stan

analyse_php_stan_max: ## ...
	bin/phpstan analyse --level=9 webapp/src/
	bin/phpstan analyse --level=9 webapp/tests/
.PHONY: analyse_php_stan_max


analyse_php_md: ## ...
	bin/phpmd webapp/src/ ansi cleancode,codesize,controversial,design,unusedcode        --baseline-file "${WEBAPP_DIR}/phpmd.baseline.xml"
#	bin/phpmd webapp/src/ ansi cleancode,codesize,controversial,design,unusedcode,naming --baseline-file "${WEBAPP_DIR}/phpmd.baseline.xml"
.PHONY: analyse_php_md

analyse_php_md_create-violation-baseline: ## ...
	bin/phpmd webapp/src/ ansi cleancode,codesize,controversial,design,unusedcode,naming --generate-baseline --baseline-file "${WEBAPP_DIR}/phpmd.baseline.xml"
#	bin/phpmd webapp/src/ ansi cleancode,codesize,controversial,design,unusedcode,naming --generate-baseline --baseline-file "${WEBAPP_DIR}/phpmd.baseline.xml"
.PHONY: analyse_php_md_create-violation-baseline

analyse_php_md_report_html: ## ...
	bin/phpmd webapp/src/ html cleancode,codesize,controversial,design,unusedcode        > "${AUTO_DOC_PHPMD_DIR}/PhpMD_report.html"
#	bin/phpmd webapp/src/ html cleancode,codesize,controversial,design,unusedcode,naming > "${AUTO_DOC_PHPMD_DIR}/PhpMD_report.html"
.PHONY: analyse_php_md_report_html

analyse_php_md_report_gitlab: ## ...
	bin/phpmd webapp/src/ gitlab cleancode,codesize,controversial,design,unusedcode        > "${AUTO_DOC_PHPMD_DIR}/PhpMD_gitlab-report.json"
#	bin/phpmd webapp/src/ gitlab cleancode,codesize,controversial,design,unusedcode,naming > "${AUTO_DOC_PHPMD_DIR}/PhpMD_gitlab-report.json"
.PHONY: analyse_php_md_report_gitlab


composer_install: ## ...
	cd webapp/ && composer install
.PHONY: composer_install

composer_update:
	cd webapp/ && composer update
.PHONY: composer_update

symfony_server_start:
	cd webapp/ && symfony server:start
.PHONY: symfony_server_start


# Checks for outdated packages
# ####################################################################

ci_outdated_php_packages: ## ...
	composer --version
	cd "${WEBAPP_DIR}" && composer update --no-install --no-interaction --no-progress --no-scripts --no-audit
	@if [ `git diff  --name-only | grep "composer.lock" | wc -l` -gt 0 ]; then \
		echo ""; \
		echo "----> ERROR: Some PHP packages are outdated"; \
		echo "             fix it with folling command line: "; \
		echo "                          composer update"; \
		echo ""; \
		exit 1;	 \
	fi;
.PHONY: ci_outdated_php_packages

outdated_php_packages: ## ...
	composer update --working-dir=${WEBAPP_DIR} --no-install --no-audit --dry-run --no-interaction --no-progress --no-scripts
#	composer update --working-dir=${WEBAPP_DIR} --no-install --no-audit --dry-run --no-interaction --no-progress --no-scripts 2>&1 | grep "Nothing to modify in lock file"
.PHONY: outdated_php_packages

# Checks for security vulnerability
# ####################################################################

# Check WEBAPP security with `composer audit` command line
# - checks for security vulnerability advisories
# - based only on the installed packages [ vendor/ ]
# - use :  GitHub Advisory Database           https://github.com/advisories
#          PHP Security Advisories Database   https://github.com/FriendsOfPHP/security-advisories
security_vendor: ## ...
	cd webapp/ && composer audit
.PHONY: security_vendor

# Check WEBAPP security with `composer audit --locked` command line
# - checks for security vulnerability advisories
# - based only on the composer.lock file (including dev packages)
# - use :  GitHub Advisory Database           https://github.com/advisories
#          PHP Security Advisories Database   https://github.com/FriendsOfPHP/security-advisories
security_composer.lock: ## ...
	cd webapp/  && composer audit --locked
.PHONY: security_composer.lock

# Check WEBAPP security with Symfony-CLI
# - checks for security vulnerability advisories
# - based only on the composer.lock file (including dev packages)
# - use :  PHP Security Advisories Database   https://github.com/FriendsOfPHP/security-advisories
security_composer.lock_via-symfony-cli: ## ...
	symfony check:security --dir=webapp/ --format=ansi
.PHONY: security_composer.lock_via-symfony-cli

# Check WEBAPP security with TRIVY
# - checks webapp for security vulnerability advisories
# - based only on the composer.lock file, (excluding dev packages)
# - use :  GitHub Advisory Database           https://github.com/advisories
#          PHP Security Advisories Database   https://github.com/FriendsOfPHP/security-advisories
security_composer.lock_via-trivy: ## ...
	cd webapp/                                                       && \
 	trivy fs .  --dependency-tree                                       \
			 	--scanners vuln                                         \
				--skip-dirs documentation/developer/vagrant_prototype/
.PHONY: security_composer.lock_via-trivy

# Check repository security with TRIVY for security, config and secret vulnerabilities
# - checks repository for security, config and secret vulnerabilities
check-security_via-trivy: ## ...
	trivy scan2html fs --scanners vuln,secret,misconfig,license . "${AUTO_DOC_SECURITY_DIR}/security-report_via-trivy-scan2html.html"
	trivy fs . --dependency-tree                                       \
			   --scanners vuln,misconfig,secret,license                \
			   --skip-dirs documentation/
.PHONY: check-security_via-trivy

# Software Bill of Materials (SBOM)
# ####################################################################
sbom_via_trivy: ## ...
	trivy fs --scanners vuln --format cyclonedx --output "${AUTO_DOC_SBOM_DIR}/sbom_cyclonedx.json"       webapp/
	trivy fs --scanners vuln --format spdx-json --output "${AUTO_DOC_SBOM_DIR}/sbom_spdx.json"            webapp/
	trivy fs --scanners vuln --format spdx      --output "${AUTO_DOC_SBOM_DIR}/sbom_spdx.spdx"            webapp/
	trivy scan2html fs 		 --format spdx    webapp/	 "${AUTO_DOC_SBOM_DIR}/sbom_spdx_report.html"
	trivy sbom "${AUTO_DOC_SBOM_DIR}/sbom_cyclonedx.json"
.PHONY: sbom_via_trivy


# ######################################################################


phive_clean: ## ...
	rm -vr ~/.phive/
.PHONY: phive_clean

phive_clean_full: ## ...
	rm -vr ~/.phive/
	rm -vr ./bin/.phive/
.PHONY: phive_clean_full

phive_install: ## ...
	phive install
#	phive install --force-accept-unsigned
.PHONY: phive_install

phive_install_auto-trust-of-predefined-gpg-keys: ## ...
#	phive install --force-accept-unsigned php-parallel-lint/php-parallel-lint
	phive install --force-accept-unsigned --trust-gpg-keys \
661E97400F658E25,96141E4421A9B0D5,033E5F8D801A2F8D,F4D32E2C9343B2AE,\
B8F640134AB1782E,AA36B9960B5B823D,C5095986493B4AA0,8101FB57DD8130F0,95DE904AB800754A11D80B605E6DDE998AB73B8E,\
4AA394086372C20A,9093F8B32E4815AA,51C67305FFC2E5C0,E82B2FB314E9906E,12CE0F1D262429A5
#        661E97400F658E25  ---> captainhook
#        96141E4421A9B0D5  ---> churn
#        033E5F8D801A2F8D  ---> composer-require-checker
#        F4D32E2C9343B2AE  ---> composer-unused
#        B8F640134AB1782E  ---> deptrac
#        AA36B9960B5B823D  ---> grumphp
#        C5095986493B4AA0  ---> infection
#        8101FB57DD8130F0  ---> phan
#        95DE904AB800754A11D80B605E6DDE998AB73B8E  ---> phpcbf, phpcs
#        4AA394086372C20A  ---> phpcpd, phploc, phpunit
#        9093F8B32E4815AA  ---> phpmd
#        51C67305FFC2E5C0  ---> phpstan
#        E82B2FB314E9906E  ---> php-cs-fixer
#                          ---> php-parallel-lint  ---> TODO use --force-accept-unsigned option
#        12CE0F1D262429A5  ---> psalm
.PHONY: phive_install_auto-trust-of-predefined-gpg-keys

# Default goal and help
##
##--- 🆘  HELP -----------------------------------------------------------------
.DEFAULT_GOAL := help
help: ## Show this help.
	@echo "Makefile COMPTOIR-DU-LIBRE"
	@echo ""
	@echo "Usage: make [target]"
	@echo "---------------------------"
	@echo ""
	@echo "Targets:"
	@grep -E '(^[a-zA-Z0-9_-]+:.*?##.*$$)|(^##)' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}{printf "\033[32m%-30s\033[0m %s\n", $$1, $$2}' | sed -e 's/\[32m##/[33m/'
#	@grep -E '(^[a-zA-Z_-]+:.*?##.*$$)|(^##)' $(MAKEFILE_LIST) | sed -e 's/^Makefile:\(.*\)/\1/' | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[32m%-30s\033[0m %s\n", $$1, $$2}' | sed -e 's/\[32m##/[33m/'
.PHONY: help
#---------------------------------------------#