# Makefile
# Check if .env file exists, if not, copy from .env.example
ifeq ($(wildcard .env),)
	cp -r .env.example .env
endif

# Get user and group IDs for chown in Dockerfile
ARG_UID=$(shell id -u)
ARG_GUID=$(shell id -g)
export ARG_UID
export ARG_GID
# Include base ENV variables
include .env

# Make commands be run with `bash` instead of the default `sh`.
SHELL='/bin/bash'
DOCKER_COMPOSE = docker compose

# example few file: docker-compose.yml:docker-compose.ov.yml
# export COMPOSE_FILE = docker-compose.yml:docker-compose.local.yml

# Setup ——————————————————————————————————————————————————————————————————————
.DEFAULT_GOAL := help

# .DEFAULT: If command does not exist in this makefile
# default:  If no command was specified:
.DEFAULT default:
	@:

# Catch-all rule for extra arguments
%:
	@:

## ——  Project Makefile  —————————————————————————————————————————————————————

help: ## Outputs this help screen
	@grep -E '(^[a-zA-Z_-]+:.*?##.*$$)|(^##)' $(MAKEFILE_LIST) | sed -e 's/Makefile://' | awk 'BEGIN {FS = ":.*?## "}{printf "\033[32m%-30s\033[0m %s\n", $$1, $$2}' | sed -e 's/\[32m##/[33m/'

## ——  Manage  ———————————————————————————————————————————————————————————————
init: init-ci app-ready ## Project init

init-ci: docker-version \
	docker-down-clear \
	app-clear \
	docker-pull docker-build docker-up \
	app-init \
	docker-info

up: docker-up ## Project up
up-db: docker-up-db ## Database services up
up-minio: docker-up-minio ## MinIO up
up-mailpit: docker-up-mailpit ## Mailpit up
down: docker-down ## Project down
down-db: docker-down-db ## Database services down
down-minio: docker-down-minio ## MinIO down
down-mailpit: docker-down-mailpit ## Mailpit down
restart: down up ## Project restart

#check: app-check ## app-test app-seeds  ## Run project linters & tests

docker-version:
	docker -v

docker-up:
	${DOCKER_COMPOSE} up -d
	${DOCKER_COMPOSE} run --rm minio-setup

docker-up-db:
	${DOCKER_COMPOSE} up -d postgres mysql

docker-down:
	${DOCKER_COMPOSE} down --remove-orphans

docker-down-db:
	${DOCKER_COMPOSE} stop postgres mysql

docker-up-stripe:
	${DOCKER_COMPOSE} --profile stripe up -d stripe-cli

docker-down-stripe:
	${DOCKER_COMPOSE} --profile stripe down stripe-cli

docker-up-mailpit:
	${DOCKER_COMPOSE} up -d mailpit

docker-down-mailpit:
	${DOCKER_COMPOSE} down mailpit

docker-up-minio:
	${DOCKER_COMPOSE} up -d minio
	${DOCKER_COMPOSE} run --rm minio-setup

docker-down-minio:
	${DOCKER_COMPOSE} down minio

docker-down-clear:
	${DOCKER_COMPOSE} down -v --remove-orphans

docker-restart-stripe: docker-down-stripe docker-up-stripe

docker-logs-stripe:
	${DOCKER_COMPOSE} --profile stripe logs stripe-cli -f

docker-info:
	${DOCKER_COMPOSE} ps

npm: pnpm

pnpm: ## Run pnpm commands in app-node-cli (e.g. make pnpm db:migrate)
	${DOCKER_COMPOSE} run --rm app-node-cli pnpm $(filter-out $@,$(MAKECMDGOALS))

docker-pull:
	${DOCKER_COMPOSE} pull --ignore-pull-failures

docker-build:
	${DOCKER_COMPOSE} --progress=plain build --build-arg BUILDKIT_INLINE_CACHE=1 --pull

docker-db-dump:
	${DOCKER_COMPOSE} exec postgres pg_dump ${POSTGRES_DB} --user=${POSTGRES_USER} > dump.sql

push-dev-cache:
	${DOCKER_COMPOSE} push

## —— App ————————————————————————————————————————————————————————————————————
app-clear: ## Clear (cache, temp file, etc)
	docker run --rm -v ${PWD}:/app --workdir=/app alpine:3.20 rm -f .ready

## Init app
app-init: app-ready

#app-pnpm-install: ## npm install
#	$(DOCKER_COMPOSE) run --remove-orphans --rm app-node-cli  pnpm install --force

#app-db-seeds: ## Run seeds
#	$(DOCKER_COMPOSE) run --rm app-node-cli ./node_modules/.bin/pnpm env-cmd -f .env tsx scripts/seed.ts


app-ready:
	docker run --rm -v ${PWD}/src:/app/src --workdir=/app alpine:3.20 touch .ready


#app-check:  ## Run tests
#	$(DOCKER_COMPOSE) run --rm app-node-cli npm run lint --remove-orphans && exit 0
#	$(DOCKER_COMPOSE) run --rm app-node-cli npm run format:check --remove-orphans && exit 0

## —— Build project ———————————————————————————————————————————————————————————————————

pull-dev-cache:
	docker pull ${REGISTRY_IMAGE}/app-nginx:latest || true
	docker pull ${REGISTRY_IMAGE}/app-node:latest || true


build: build-push-app ## Build project images

build-push-app:
	if ! docker buildx inspect kbh-builder >/dev/null 2>&1; then \
		docker buildx create --name kbh-builder --driver docker-container --use; \
	else \
		docker buildx use kbh-builder; \
	fi
	docker buildx inspect --bootstrap

	docker buildx build --progress=plain --pull \
		--file=Dockerfile \
		--target runner \
		--build-arg="NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL}" \
		--build-arg="NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=${NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY}" \
		--cache-from type=registry,ref=${REGISTRY_IMAGE}/app-node-cache:latest \
		--cache-to type=registry,ref=${REGISTRY_IMAGE}/app-node-cache:latest,mode=max \
		--tag ${REGISTRY_IMAGE}/app-node:latest \
		--tag ${REGISTRY_IMAGE}/app-node:${COMMIT_REF_SLUG}-${COMMIT_SHA}-${PIPELINE_ID} \
		--tag ${REGISTRY_IMAGE}/app-node:${COMMIT_REF_SLUG} \
		--load \
		. \
		--push

	docker buildx build --progress=plain --pull \
		--file=Dockerfile \
		--target nginx \
		--cache-from type=registry,ref=${REGISTRY_IMAGE}/app-node-cache:latest \
		--cache-to type=registry,ref=${REGISTRY_IMAGE}/app-node-cache:latest,mode=max \
		--tag ${REGISTRY_IMAGE}/app-nginx:latest \
		--tag ${REGISTRY_IMAGE}/app-nginx:${COMMIT_REF_SLUG}-${COMMIT_SHA}-${PIPELINE_ID} \
		--tag ${REGISTRY_IMAGE}/app-nginx:${COMMIT_REF_SLUG} \
		--load \
		. \
		--push

deploy: ## Deploy project
	ssh -o StrictHostKeyChecking=no ${USER}@${HOST} -p ${PORT} 'docker network create --driver=overlay kbh-traefik-proxy || true'
	ssh -o StrictHostKeyChecking=no ${USER}@${HOST} -p ${PORT} 'mkdir -p www'
	ssh -o StrictHostKeyChecking=no ${USER}@${HOST} -p ${PORT} 'cd www && mkdir -p app'
	ssh -o StrictHostKeyChecking=no ${USER}@${HOST} -p ${PORT} 'cd www/app && rm -rf build_${BUILD_NUMBER} && mkdir build_${BUILD_NUMBER}'
	envsubst < ${DOCKER_COMPOSE_FILE}.yml > ${DOCKER_COMPOSE_FILE}-env.yml
	scp -o StrictHostKeyChecking=no -P ${PORT} ${DOCKER_COMPOSE_FILE}-env.yml ${USER}@${HOST}:www/app/build_${BUILD_NUMBER}/docker-compose.yml
	rm -f ${DOCKER_COMPOSE_FILE}-env.yml
	ssh -o StrictHostKeyChecking=no ${USER}@${HOST} -p ${PORT} 'cd www/app/build_${BUILD_NUMBER} && docker login -u gitlab-ci-token -p "${CI_JOB_TOKEN}" "${CI_REGISTRY}"'
	ssh -o StrictHostKeyChecking=no ${USER}@${HOST} -p ${PORT} 'cd www/app/build_${BUILD_NUMBER} && docker stack deploy --compose-file docker-compose.yml kbh --with-registry-auth --prune'

deploy-clean: ## Clean temp file after deploy
	rm -f ${DOCKER_COMPOSE_FILE}-env.yml
