# ============================================================
#  Frappe ERP — управление стеком
#  Использование: make <target>
# ============================================================

SHELL := /bin/bash
SITE  ?= erp.local
TAG   ?= v16

COMPOSE_OVERRIDES := \
  -f compose.yaml \
  -f overrides/compose.mariadb.yaml \
  -f overrides/compose.redis.yaml \
  -f overrides/compose.assets-volume.yaml \
  -f overrides/compose.noproxy.yaml \
  -f overrides/compose.local-origin.yaml \
  -f overrides/compose.backup-cron.yaml

COMPOSE_DEV := $(COMPOSE_OVERRIDES) \
  -f overrides/compose.picking-dev.yaml

APPS_JSON_B64 := $(shell base64 -w 0 apps.json)

# Приложения с pre-built esbuild-бандлами (public/dist/).
# Vue SPA (crm, builder, helpdesk, insights, gameplan, drive) используют public/frontend/ —
# они синхронизируются отдельной веткой внутри sync-assets.
DIST_APPS := frappe erpnext hrms lms print_designer webshop education lending newsletter

# Имя именованного тома Docker Compose (проект = имя директории)
COMPOSE_PROJECT := $(notdir $(CURDIR))
ASSETS_VOL      := $(COMPOSE_PROJECT)_assets

.PHONY: help build up down restart recreate-frontend update migrate assets sync-assets backup logs ps shell

# ── Справка ─────────────────────────────────────────────────
help:
	@echo ""
	@echo "  Frappe ERP — доступные команды:"
	@echo ""
	@echo "  Образ:"
	@echo "    make build          — собрать frappe-custom:$(TAG) из apps.json"
	@echo "    make build TAG=v17  — собрать с другим тегом"
	@echo ""
	@echo "  Стек:"
	@echo "    make up             — запустить все контейнеры"
	@echo "    make down           — остановить и удалить контейнеры"
	@echo "    make restart        — перезапустить backend/frontend"
	@echo "    make ps             — статус контейнеров"
	@echo ""
	@echo "  Обновление:"
	@echo "    make update         — rebuild образа + up + migrate + assets"
	@echo "    make migrate        — bench migrate на сайте $(SITE)"
	@echo "    make assets         — пересобрать JS/CSS бандлы и синхронизировать"
	@echo "    make sync-assets    — скопировать dist в assets volume (очищает кэш, затем копирует)"
	@echo ""
	@echo "  Обслуживание:"
	@echo "    make backup         — создать резервную копию сайта"
	@echo "    make logs           — логи backend (live)"
	@echo "    make shell          — bash в backend контейнере"
	@echo ""

# ── Сборка образа ────────────────────────────────────────────
build:
	@echo "→ Сборка frappe-custom:$(TAG) из apps.json..."
	docker build \
	  --build-arg APPS_JSON_BASE64=$(APPS_JSON_B64) \
	  --build-arg FRAPPE_BRANCH=version-16 \
	  -t frappe-custom:$(TAG) \
	  -f images/layered/Containerfile \
	  .
	@echo "✓ Образ frappe-custom:$(TAG) готов"

# ── Запуск стека ─────────────────────────────────────────────
up:
	docker compose $(COMPOSE_OVERRIDES) up -d
	@echo "✓ Стек запущен. Сайт: http://localhost:$${HTTP_PUBLISH_PORT:-8090}"

down:
	docker compose $(COMPOSE_OVERRIDES) down

restart:
	docker compose $(COMPOSE_OVERRIDES) restart backend frontend websocket

recreate-frontend:
	docker compose $(COMPOSE_OVERRIDES) up -d --no-deps --force-recreate frontend

ps:
	docker compose $(COMPOSE_OVERRIDES) ps

# ── Обновление (полный цикл) ─────────────────────────────────
update: build
	@echo "→ Пересоздаём контейнеры с новым образом..."
	docker compose $(COMPOSE_OVERRIDES) up -d --no-deps backend websocket queue-short queue-long scheduler
	@echo "→ Ждём готовности backend..."
	sleep 10
	$(MAKE) migrate
	$(MAKE) assets
	docker compose $(COMPOSE_OVERRIDES) restart frontend
	@echo "✓ Обновление завершено"

# ── Миграции БД ──────────────────────────────────────────────
migrate:
	@echo "→ bench migrate --site $(SITE)..."
	docker compose $(COMPOSE_OVERRIDES) exec backend \
	  bench --site $(SITE) migrate
	@echo "✓ Миграция завершена"

# ── Пересборка JS/CSS ────────────────────────────────────────
assets:
	@echo "→ Пересборка assets (bench build --production)..."
	docker compose $(COMPOSE_OVERRIDES) exec backend bench build --production
	$(MAKE) sync-assets
	@echo "✓ Assets пересобраны"

# ── Синхронизация dist → frappe-project_assets volume ────────
# bench build пишет файлы в overlay-слой backend-контейнера, а nginx
# читает из именованного тома. Эта цель копирует dist-файлы туда.
sync-assets:
	@echo "→ Сброс кэша перед синхронизацией (предотвращает пересоздание симлинков)..."
	@docker compose $(COMPOSE_OVERRIDES) exec backend \
	  bench --site $(SITE) clear-cache
	@docker compose $(COMPOSE_OVERRIDES) exec backend bash -c \
	  ". /home/frappe/frappe-bench/env/bin/activate && \
	   python -c \"import redis; r=redis.Redis(host='redis-cache'); \
	   deleted=r.delete('assets_json'); \
	   print('assets_json удалён из Redis' if deleted else 'assets_json отсутствовал')\""
	@echo "→ Синхронизация dist-файлов в $(ASSETS_VOL)..."
	@TMPDIR=$$(mktemp -d) && \
	trap "rm -rf $$TMPDIR" EXIT && \
	BACKEND=$$(docker compose $(COMPOSE_OVERRIDES) ps -q backend) && \
	docker cp $$BACKEND:/home/frappe/frappe-bench/sites/assets/assets.json \
	  $$TMPDIR/assets.json && \
	for app in $(DIST_APPS); do \
	  SRC=/home/frappe/frappe-bench/apps/$$app/$$app/public/dist; \
	  if docker cp $$BACKEND:$$SRC $$TMPDIR/$$app-dist 2>/dev/null; then \
	    echo "  ✓ $$app"; \
	  else \
	    echo "  - $$app (нет dist, пропущено)"; \
	  fi; \
	done && \
	docker run --rm \
	  -v $$TMPDIR:/src:ro \
	  -v $(ASSETS_VOL):/assets \
	  alpine sh -c ' \
	    cp -f /src/assets.json /assets/assets.json; \
	    for d in /src/*-dist; do \
	      [ -d "$$d" ] || continue; \
	      app=$$(basename "$$d" -dist); \
	      if [ -L "/assets/$$app" ]; then rm -f "/assets/$$app"; \
	      elif [ -d "/assets/$$app" ]; then rm -rf "/assets/$$app"; fi; \
	      mkdir -p "/assets/$$app/dist"; \
	      cp -rf "$$d/." "/assets/$$app/dist/"; \
	    done \
	  '
	@docker compose $(COMPOSE_OVERRIDES) up -d --no-deps --force-recreate frontend
	@echo "✓ Синхронизация завершена"

# ── Резервная копия ──────────────────────────────────────────
backup:
	@echo "→ Создание резервной копии сайта $(SITE)..."
	docker compose $(COMPOSE_OVERRIDES) exec backend \
	  bench --site $(SITE) backup --with-files
	@echo "✓ Бэкап создан (см. sites/$(SITE)/private/backups/)"

# ── Разработка picking_app ───────────────────────────────────
# Монтирует /home/mkr/picking_app как volume — изменения в VS Code
# сразу видны без пересборки образа.
dev-up:
	docker compose $(COMPOSE_DEV) up -d --no-deps --force-recreate \
	  backend websocket queue-short queue-long scheduler
	@echo "→ Пересоздаём frontend (сброс кешированных IP backend)..."
	docker compose $(COMPOSE_OVERRIDES) up -d --no-deps --force-recreate frontend
	@echo "✓ Dev-режим активен. Исходники: /home/mkr/picking_app"
	@echo "  Страница: http://localhost:8090/app/picking-mobile"

dev-down:
	docker compose $(COMPOSE_OVERRIDES) up -d --no-deps --force-recreate \
	  backend websocket queue-short queue-long scheduler
	docker compose $(COMPOSE_OVERRIDES) restart frontend
	@echo "✓ Dev-режим выключен, volume-монтирование снято"

dev-reload:
	@echo "→ Сброс кэша Frappe..."
	docker compose $(COMPOSE_DEV) exec backend bench --site $(SITE) clear-cache
	@echo "✓ Кэш сброшен — перезагрузи страницу в браузере"

# ── Логи и отладка ───────────────────────────────────────────
logs:
	docker compose $(COMPOSE_OVERRIDES) logs -f backend

logs-picking:
	docker compose $(COMPOSE_OVERRIDES) logs -f backend | grep -i "picking\|error\|exception\|traceback" --color

shell:
	docker compose $(COMPOSE_OVERRIDES) exec backend bash
