# ==============================================================================
# DIRECTORIES
# ==============================================================================
DIR_ROOT       := $(dir $(abspath $(MAKEFILE_LIST)))
DIR_BIN        := $(addsuffix /, $(DIR_ROOT))

# ==============================================================================
# TOOLS
# ==============================================================================
SHADER_CMAKE   := $(DIR_ROOT)tools/shaders/compile_spirv.cmake
SHADERS_DIR    := $(DIR_ROOT)data/shaders
HEADERS_DIR    := $(DIR_ROOT)source/core/rendering/sdl3gpu
ifeq ($(OS),Windows_NT)
    GLSLC      := $(shell where glslc 2>NUL)
else
    GLSLC      := $(shell command -v glslc 2>/dev/null)
endif

# ==============================================================================
# TARGET NAMES
# ==============================================================================
TARGET_NAME    := aee
TARGET_FILE    := $(DIR_BIN)$(TARGET_NAME)
APP_NAME       := Aventures en Egipte
DIST_DIR       := dist
RELEASE_FOLDER := dist/_tmp
RELEASE_FILE   := $(RELEASE_FOLDER)/$(TARGET_NAME)

# ==============================================================================
# VERSION (extracted from defines.hpp)
# ==============================================================================
ifeq ($(OS),Windows_NT)
    VERSION := $(shell powershell -Command "(Select-String -Path 'source/game/defines.hpp' -Pattern 'constexpr const char\* VERSION = \"(.+?)\"').Matches.Groups[1].Value")
else
    VERSION := $(shell grep 'constexpr const char\* VERSION' source/game/defines.hpp | sed -E 's/.*VERSION = "([^"]+)".*/\1/')
endif

# ==============================================================================
# GIT HASH (computat al host, passat a CMake via -DGIT_HASH)
# Evita que CMake haja de cridar git des de Docker/emscripten on falla per
# "dubious ownership" del volum muntat.
# ==============================================================================
ifeq ($(OS),Windows_NT)
    GIT_HASH := $(shell git rev-parse --short=7 HEAD 2>NUL)
else
    GIT_HASH := $(shell git rev-parse --short=7 HEAD 2>/dev/null)
endif
ifeq ($(GIT_HASH),)
    GIT_HASH := unknown
endif

# ==============================================================================
# SHELL (Windows usa cmd.exe para que las recetas con powershell funcionen igual
# desde cualquier terminal: PowerShell, cmd o git-bash)
# ==============================================================================
ifeq ($(OS),Windows_NT)
    SHELL := cmd.exe
endif

# ==============================================================================
# WINDOWS-SPECIFIC VARIABLES
# ==============================================================================
ifeq ($(OS),Windows_NT)
    WIN_TARGET_FILE    := $(DIR_BIN)$(APP_NAME)
    WIN_RELEASE_FILE   := $(RELEASE_FOLDER)/$(APP_NAME)
    # Escapa apòstrofs per a PowerShell (duplica ' → ''). Sense això, APP_NAMEs
    # com "JailDoctor's Dilemma" trencarien el parsing de -Destination '...'.
    WIN_RELEASE_FILE_PS := $(subst ','',$(WIN_RELEASE_FILE))
else
    WIN_TARGET_FILE    := $(TARGET_FILE)
    WIN_RELEASE_FILE   := $(RELEASE_FILE)
    WIN_RELEASE_FILE_PS := $(WIN_RELEASE_FILE)
endif

# ==============================================================================
# RELEASE NAMES
# ==============================================================================
WINDOWS_RELEASE             := $(DIST_DIR)/$(TARGET_NAME)-$(VERSION)-win32-x64.zip
MACOS_INTEL_RELEASE         := $(DIST_DIR)/$(TARGET_NAME)-$(VERSION)-macos-intel.dmg
MACOS_APPLE_SILICON_RELEASE := $(DIST_DIR)/$(TARGET_NAME)-$(VERSION)-macos-apple-silicon.dmg
LINUX_RELEASE               := $(DIST_DIR)/$(TARGET_NAME)-$(VERSION)-linux.tar.gz

# ==============================================================================
# PLATAFORMA
# ==============================================================================
ifeq ($(OS),Windows_NT)
    FixPath         = $(subst /,\\,$1)
    RM              := del /Q
    MKDIR           := mkdir
else
    FixPath         = $1
    RMFILE          := rm -f
    RMDIR           := rm -rdf
    MKDIR           := mkdir -p
    UNAME_S         := $(shell uname -s)
endif

# ==============================================================================
# CMAKE GENERATOR (Windows needs explicit MinGW Makefiles generator)
# ==============================================================================
ifeq ($(OS),Windows_NT)
    CMAKE_GEN := -G "MinGW Makefiles"
else
    CMAKE_GEN :=
endif

# ==============================================================================
# COMPILACIÓN CON CMAKE
# ==============================================================================
all:
	@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH)
	@cmake --build build

debug:
	@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Debug -DGIT_HASH=$(GIT_HASH)
	@cmake --build build

# ==============================================================================
# REGLAS PARA COMPILACIÓN DE SHADERS (multiplataforma via cmake)
# ==============================================================================
compile_shaders:
ifdef GLSLC
	@cmake -D GLSLC=$(GLSLC) -D SHADERS_DIR=$(SHADERS_DIR) -D HEADERS_DIR=$(HEADERS_DIR) -P $(SHADER_CMAKE)
else
	@echo "glslc no encontrado - asegurate de que los headers SPIR-V precompilados existen"
endif

# Empaqueta data/ a resources.pack (format AEE1). Build previ de l'eina + execució.
pack:
	@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH)
	@cmake --build build --target pack_resources
	@./build/pack_resources data resources.pack

# ==============================================================================
# RELEASE AUTOMÁTICO (detecta SO)
# ==============================================================================
release:
ifeq ($(OS),Windows_NT)
	@"$(MAKE)" _windows_release
else
ifeq ($(UNAME_S),Darwin)
	@$(MAKE) _macos_release
else
	@$(MAKE) _linux_release
endif
endif

# ==============================================================================
# COMPILACIÓN PARA WINDOWS (RELEASE)
# ==============================================================================
_windows_release: pack
	@echo off
	@echo Creando release para Windows - Version: $(VERSION)

# Compila con cmake
	@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH)
	@cmake --build build

# Crea carpeta de distribución y carpeta temporal 'RELEASE_FOLDER'
	@powershell -Command "if (-not (Test-Path '$(DIST_DIR)')) {New-Item '$(DIST_DIR)' -ItemType Directory}"
	@powershell -Command "if (Test-Path '$(RELEASE_FOLDER)') {Remove-Item '$(RELEASE_FOLDER)' -Recurse -Force}"
	@powershell -Command "if (-not (Test-Path '$(RELEASE_FOLDER)')) {New-Item '$(RELEASE_FOLDER)' -ItemType Directory}"

# Copia ficheros (resources.pack substitueix la carpeta data/)
	@powershell -Command "Copy-Item 'resources.pack' -Destination '$(RELEASE_FOLDER)'"
	@powershell -Command "Copy-Item 'LICENSE' -Destination '$(RELEASE_FOLDER)'"
	@powershell -Command "Copy-Item 'README.md' -Destination '$(RELEASE_FOLDER)'"
	@powershell -Command "Copy-Item 'gamecontrollerdb.txt' -Destination '$(RELEASE_FOLDER)'"
	@powershell -Command "Copy-Item 'release\windows\dll\*.dll' -Destination '$(RELEASE_FOLDER)'"
	@powershell -Command "Copy-Item -Path '$(TARGET_FILE).exe' -Destination '$(WIN_RELEASE_FILE_PS).exe'"
	strip -s -R .comment -R .gnu.version "$(WIN_RELEASE_FILE).exe" --strip-unneeded

# Crea el fichero .zip
	@powershell -Command "if (Test-Path '$(WINDOWS_RELEASE)') {Remove-Item '$(WINDOWS_RELEASE)'}"
	@powershell -Command "Compress-Archive -Path '$(RELEASE_FOLDER)/*' -DestinationPath '$(WINDOWS_RELEASE)'"
	@echo Release creado: $(WINDOWS_RELEASE)

# Elimina la carpeta temporal 'RELEASE_FOLDER'
	@powershell -Command "if (Test-Path '$(RELEASE_FOLDER)') {Remove-Item '$(RELEASE_FOLDER)' -Recurse -Force}"

# ==============================================================================
# COMPILACIÓN PARA MACOS (RELEASE)
# ==============================================================================
_macos_release: pack
	@echo "Creando release para macOS - Version: $(VERSION)"

# Verifica dependencias necesarias (create-dmg). Si falta, intenta instalarla
# con brew; si brew tampoco está, indica el comando exacto al usuario.
	@command -v create-dmg >/dev/null 2>&1 || { \
		echo ""; \
		echo "============================================"; \
		echo "  Falta la dependencia: create-dmg"; \
		echo "============================================"; \
		if command -v brew >/dev/null 2>&1; then \
			echo "  Instalando con: brew install create-dmg"; \
			brew install create-dmg || { \
				echo ""; \
				echo "  ERROR: 'brew install create-dmg' ha fallado."; \
				echo "  Ejecuta el comando manualmente y vuelve a probar."; \
				exit 1; \
			}; \
		else \
			echo "  Homebrew no está instalado."; \
			echo "  Instálalo desde https://brew.sh y luego ejecuta:"; \
			echo "      brew install create-dmg"; \
			exit 1; \
		fi; \
	}

# Elimina datos de compilaciones anteriores
	$(RMDIR) "$(RELEASE_FOLDER)"
	$(RMFILE) tmp.dmg
	$(RMFILE) "$(DIST_DIR)"/rw.*
	$(RMFILE) "$(MACOS_INTEL_RELEASE)"
	$(RMFILE) "$(MACOS_APPLE_SILICON_RELEASE)"

# Crea la carpeta temporal para hacer el trabajo y las carpetas obligatorias para crear una app de macOS
	$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks"
	$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS"
	$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"

# Copia carpetas y ficheros (resources.pack substitueix la carpeta data/)
	cp resources.pack "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
	cp gamecontrollerdb.txt "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
	cp -R release/macos/frameworks/SDL3.xcframework/macos-arm64_x86_64/SDL3.framework "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks"
	cp release/icons/*.icns "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
	cp release/macos/Info.plist "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents"
	cp LICENSE "$(RELEASE_FOLDER)"
	cp README.md "$(RELEASE_FOLDER)"

# Actualiza versión en Info.plist
	@echo "Actualizando Info.plist con versión $(VERSION)..."
	@RAW_VERSION=$$(echo "$(VERSION)" | sed 's/^v//'); \
	sed -i '' '/<key>CFBundleShortVersionString<\/key>/{n;s|<string>.*</string>|<string>'"$$RAW_VERSION"'</string>|;}' "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist"; \
	sed -i '' '/<key>CFBundleVersion<\/key>/{n;s|<string>.*</string>|<string>'"$$RAW_VERSION"'</string>|;}' "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist"

# Compila y empaqueta la versión Intel (best-effort: si falla, se omite el
# DMG Intel y continúa con la build de Apple Silicon).
	@echo ""
	@echo "============================================"
	@echo "  Compilando version Intel (x86_64)"
	@echo "============================================"
	@if cmake -S . -B build/intel -DCMAKE_BUILD_TYPE=Release \
	          -DCMAKE_OSX_ARCHITECTURES=x86_64 \
	          -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 \
	          -DMACOS_BUNDLE=ON -DGIT_HASH=$(GIT_HASH) \
	   && cmake --build build/intel; then \
		cp "$(TARGET_FILE)" "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS/$(TARGET_NAME)"; \
		codesign --deep --force --sign - --timestamp=none "$(RELEASE_FOLDER)/$(APP_NAME).app"; \
		echo "Creando DMG Intel con iconos de 96x96..."; \
		create-dmg \
		  --volname "$(APP_NAME)" \
		  --window-pos 200 120 \
		  --window-size 720 300 \
		  --icon-size 96 \
		  --text-size 12 \
		  --icon "$(APP_NAME).app" 278 102 \
		  --icon "LICENSE" 441 102 \
		  --icon "README.md" 604 102 \
		  --app-drop-link 115 102 \
		  --hide-extension "$(APP_NAME).app" \
		  "$(MACOS_INTEL_RELEASE)" \
		  "$(RELEASE_FOLDER)" || true; \
		echo "Release Intel creado: $(MACOS_INTEL_RELEASE)"; \
	else \
		echo ""; \
		echo "============================================"; \
		echo "  WARNING: la build Intel ha fallado."; \
		echo "  Se omite el DMG Intel y se continúa con"; \
		echo "  la build de Apple Silicon."; \
		echo "============================================"; \
		echo ""; \
	fi

# Compila la versión para procesadores Apple Silicon con cmake
	@echo ""
	@echo "============================================"
	@echo "  Compilando version Apple Silicon (arm64)"
	@echo "============================================"
	@cmake -S . -B build/arm -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 -DMACOS_BUNDLE=ON -DGIT_HASH=$(GIT_HASH)
	@cmake --build build/arm
	cp "$(TARGET_FILE)" "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS/$(TARGET_NAME)"

# Firma la aplicación
	codesign --deep --force --sign - --timestamp=none "$(RELEASE_FOLDER)/$(APP_NAME).app"

# Empaqueta el .dmg de la versión Apple Silicon con create-dmg
	@echo "Creando DMG Apple Silicon con iconos de 96x96..."
	create-dmg \
	  --volname "$(APP_NAME)" \
	  --window-pos 200 120 \
	  --window-size 720 300 \
	  --icon-size 96 \
	  --text-size 12 \
	  --icon "$(APP_NAME).app" 278 102 \
	  --icon "LICENSE" 441 102 \
	  --icon "README.md" 604 102 \
	  --app-drop-link 115 102 \
	  --hide-extension "$(APP_NAME).app" \
	  "$(MACOS_APPLE_SILICON_RELEASE)" \
	  "$(RELEASE_FOLDER)" || true
	@echo "Release Apple Silicon creado: $(MACOS_APPLE_SILICON_RELEASE)"

# Elimina las carpetas temporales
	$(RMDIR) "$(RELEASE_FOLDER)"
	$(RMDIR) build/intel
	$(RMDIR) build/arm
	$(RMFILE) "$(DIST_DIR)"/rw.*

# ==============================================================================
# COMPILACIÓN PARA WEBASSEMBLY (requiere Docker amb emscripten/emsdk)
# ==============================================================================
# Genera aee.{html,js,wasm,data} a dist/wasm/. Es pot provar servint amb un
# servidor HTTP local (els navegadors no carreguen `file://` WASM):
#   cd dist/wasm && python3 -m http.server 8000
#   # després obrir http://localhost:8000/aee.html
wasm:
	@echo "Creando release para WebAssembly - Version: $(VERSION)"
	docker run --rm \
		--user $(shell id -u):$(shell id -g) \
		-v $(DIR_ROOT):/src \
		-w /src \
		emscripten/emsdk:latest \
		bash -c "emcmake cmake -S . -B build/wasm -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH) && cmake --build build/wasm"
	@$(MKDIR) "$(DIST_DIR)/wasm"
	@cp build/wasm/$(TARGET_NAME).html $(DIST_DIR)/wasm/
	@cp build/wasm/$(TARGET_NAME).js $(DIST_DIR)/wasm/
	@cp build/wasm/$(TARGET_NAME).wasm $(DIST_DIR)/wasm/
	@cp build/wasm/$(TARGET_NAME).data $(DIST_DIR)/wasm/
	@echo "Output: $(DIST_DIR)/wasm/$(TARGET_NAME).html"
	scp $(DIST_DIR)/wasm/$(TARGET_NAME).js $(DIST_DIR)/wasm/$(TARGET_NAME).wasm $(DIST_DIR)/wasm/$(TARGET_NAME).data \
		maverick:/home/sergio/gitea/web_jailgames/static/games/aee/wasm/
	ssh maverick 'cd /home/sergio/gitea/web_jailgames && ./deploy.sh'
	@echo "Deployed to maverick"

# Versió Debug del build wasm: build local sense deploy. Sortida a dist/wasm_debug/.
wasm_debug:
	@echo "Compilando WebAssembly Debug - Version: $(VERSION)"
	docker run --rm \
		--user $(shell id -u):$(shell id -g) \
		-v $(DIR_ROOT):/src \
		-w /src \
		emscripten/emsdk:latest \
		bash -c "emcmake cmake -S . -B build/wasm_debug -DCMAKE_BUILD_TYPE=Debug -DGIT_HASH=$(GIT_HASH) && cmake --build build/wasm_debug"
	@$(MKDIR) "$(DIST_DIR)/wasm_debug"
	@cp build/wasm_debug/$(TARGET_NAME).html $(DIST_DIR)/wasm_debug/
	@cp build/wasm_debug/$(TARGET_NAME).js $(DIST_DIR)/wasm_debug/
	@cp build/wasm_debug/$(TARGET_NAME).wasm $(DIST_DIR)/wasm_debug/
	@cp build/wasm_debug/$(TARGET_NAME).data $(DIST_DIR)/wasm_debug/
	@echo "Output: $(DIST_DIR)/wasm_debug/$(TARGET_NAME).html"

# ==============================================================================
# COMPILACIÓN PARA LINUX (RELEASE)
# ==============================================================================
_linux_release: pack
	@echo "Creando release para Linux - Version: $(VERSION)"

# Compila con cmake
	@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH)
	@cmake --build build

# Elimina carpeta temporal previa y la recrea (crea dist/ si no existe)
	$(RMDIR) "$(RELEASE_FOLDER)"
	$(MKDIR) "$(RELEASE_FOLDER)"

# Copia ficheros (resources.pack substitueix la carpeta data/)
	cp resources.pack "$(RELEASE_FOLDER)"
	cp LICENSE "$(RELEASE_FOLDER)"
	cp README.md "$(RELEASE_FOLDER)"
	cp gamecontrollerdb.txt "$(RELEASE_FOLDER)"
	cp "$(TARGET_FILE)" "$(RELEASE_FILE)"
	strip -s -R .comment -R .gnu.version "$(RELEASE_FILE)" --strip-unneeded

# Empaqueta ficheros
	$(RMFILE) "$(LINUX_RELEASE)"
	tar -czvf "$(LINUX_RELEASE)" -C "$(RELEASE_FOLDER)" .
	@echo "Release creado: $(LINUX_RELEASE)"

# Elimina la carpeta temporal
	$(RMDIR) "$(RELEASE_FOLDER)"

# ==============================================================================
# ==============================================================================
# CODE QUALITY (delegados a cmake)
# ==============================================================================
format:
	@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH)
	@cmake --build build --target format

format-check:
	@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH)
	@cmake --build build --target format-check

tidy:
	@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH)
	@cmake --build build --target tidy

tidy-fix:
	@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH)
	@cmake --build build --target tidy-fix

cppcheck:
	@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH)
	@cmake --build build --target cppcheck

# DESCÀRREGA DE GAMECONTROLLERDB
# ==============================================================================
controllerdb:
	@echo "Descarregant gamecontrollerdb.txt..."
	curl -fsSL https://raw.githubusercontent.com/mdqinc/SDL_GameControllerDB/master/gamecontrollerdb.txt \
		-o gamecontrollerdb.txt
	@echo "gamecontrollerdb.txt actualitzat"

# ==============================================================================
# AJUDA
# ==============================================================================
help:
	@echo "Makefile per a Aventures en Egipte"
	@echo "Comandes disponibles:"
	@echo ""
	@echo "  Compilacio:"
	@echo "    make                     - Compilar amb cmake (Release)"
	@echo "    make debug               - Compilar amb cmake (Debug)"
	@echo ""
	@echo "  Release:"
	@echo "    make release             - Crear release (detecta SO automaticament)"
	@echo "    make wasm                - Build WebAssembly (requereix Docker) + deploy a maverick"
	@echo "    make wasm_debug          - Build WebAssembly Debug local (sense deploy)"
	@echo ""
	@echo "  Eines:"
	@echo "    make compile_shaders     - Compilar shaders SPIR-V"
	@echo "    make pack                - Empaquetar data/ a resources.pack (format AEE1)"
	@echo "    make controllerdb        - Actualitzar gamecontrollerdb.txt des de SDL_GameControllerDB"
	@echo ""
	@echo "  Qualitat de codi:"
	@echo "    make format              - Formatar codi amb clang-format"
	@echo "    make format-check        - Verificar format sense modificar"
	@echo "    make tidy                - Anàlisi estàtic amb clang-tidy"
	@echo "    make tidy-fix            - Anàlisi estàtic amb auto-fix"
	@echo "    make cppcheck            - Anàlisi estàtic amb cppcheck"
	@echo ""
	@echo "  Altres:"
	@echo "    make help                - Mostrar esta ajuda"
	@echo ""
	@echo "  Versio actual: $(VERSION) ($(GIT_HASH))"

.PHONY: all debug pack release wasm wasm_debug _windows_release _linux_release _macos_release compile_shaders controllerdb format format-check tidy tidy-fix cppcheck help
