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

# ==============================================================================
# TARGET NAMES
# ==============================================================================
TARGET_NAME    := projecte_2026
TARGET_FILE    := $(DIR_BIN)$(TARGET_NAME)
APP_NAME       := Projecte 2026
DIST_DIR       := dist
RELEASE_FOLDER := dist/_tmp
RELEASE_FILE   := $(RELEASE_FOLDER)/$(TARGET_NAME)
RESOURCE_FILE  := release/windows/jdd.res

# ==============================================================================
# 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

# ==============================================================================
# VERSION (extracted from defines.hpp)
# ==============================================================================
ifeq ($(OS),Windows_NT)
    VERSION := v$(shell powershell -Command "(Select-String -Path 'source/utils/defines.hpp' -Pattern 'constexpr const char\* VERSION = \"(.+?)\"').Matches.Groups[1].Value")
else
    VERSION := v$(shell grep 'constexpr const char\* VERSION' source/utils/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

# ==============================================================================
# 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

# ==============================================================================
# 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

# ==============================================================================
# EMPAQUETADO DE RECURSOS (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

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

# Compila con cmake (genera shaders, resources.pack y ejecutable)
	@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
	@powershell -Command "Copy-Item -Path '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:
	@echo "Creando release para macOS - Version: $(VERSION)"

# Verificar e instalar create-dmg si es necesario
	@which create-dmg > /dev/null || (echo "Instalando create-dmg..." && brew install create-dmg)

# Compila la versión para procesadores Intel con cmake (genera shaders y resources.pack)
	@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

# 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
	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"

# Copia el ejecutable Intel al bundle
	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 Intel con create-dmg
	@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)"

# Compila la versión para procesadores Apple Silicon con cmake
	@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 LINUX (RELEASE)
# ==============================================================================
_linux_release:
	@echo "Creando release para Linux - Version: $(VERSION)"

# Compila con cmake (genera shaders, resources.pack y ejecutable)
	@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
	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)"

# ==============================================================================
# COMPILACIÓN PARA WEBASSEMBLY (requiere Docker)
# ==============================================================================
wasm:
	@echo "Compilando 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/"
	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/projecte-2026/wasm/
	ssh maverick 'cd /home/sergio/gitea/web_jailgames && ./deploy.sh'
	@echo "Deployed to maverick"

# Versión Debug del build wasm: arranca directamente a la GAME (sin logo/loading/title)
# y activa el editor y la consola. Salida a dist/wasm_debug/.
wasm_debug:
	@echo "Compilando WebAssembly Debug - Version: $(VERSION)"
	docker run --rm \
		-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/"
	scp $(DIST_DIR)/wasm_debug/$(TARGET_NAME).js $(DIST_DIR)/wasm_debug/$(TARGET_NAME).wasm $(DIST_DIR)/wasm_debug/$(TARGET_NAME).data \
		maverick:/home/sergio/gitea/web_jailgames/static/games/projecte-2026/wasm/
	ssh maverick 'cd /home/sergio/gitea/web_jailgames && ./deploy.sh'
	@echo "Deployed to maverick"

# ==============================================================================
# ==============================================================================
# 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

# DESCARGA DE GAMECONTROLLERDB
# ==============================================================================
controllerdb:
	@echo "Descargando gamecontrollerdb.txt..."
	curl -fsSL https://raw.githubusercontent.com/mdqinc/SDL_GameControllerDB/master/gamecontrollerdb.txt \
		-o gamecontrollerdb.txt
	@echo "gamecontrollerdb.txt actualizado"

# ==============================================================================
# REGLAS ESPECIALES
# ==============================================================================
# Regla para mostrar la versión actual
show_version:
	@echo "Version actual: $(VERSION)"

# Regla de ayuda
help:
	@echo "Makefile para Projecte 2026"
	@echo "Comandos disponibles:"
	@echo ""
	@echo "  Compilacion:"
	@echo "    make                 - Compilar con cmake (Release)"
	@echo "    make debug           - Compilar con cmake (Debug)"
	@echo ""
	@echo "  Release:"
	@echo "    make release         - Crear release (detecta SO automaticamente)"
	@echo ""
	@echo "  Herramientas:"
	@echo "    make compile_shaders - Compilar shaders SPIR-V"
	@echo "    make pack            - Empaquetar recursos a resources.pack"
	@echo "    make controllerdb    - Descargar gamecontrollerdb.txt actualizado"
	@echo ""
	@echo "  Calidad de codigo:"
	@echo "    make format          - Formatear codigo con clang-format"
	@echo "    make format-check    - Verificar formato sin modificar"
	@echo "    make tidy            - Analisis estatico con clang-tidy"
	@echo "    make tidy-fix        - Analisis estatico con auto-fix"
	@echo "    make cppcheck        - Analisis estatico con cppcheck"
	@echo ""
	@echo "  WebAssembly (requiere Docker):"
	@echo "    make wasm            - Compilar a WebAssembly (Release) y desplegar a maverick"
	@echo "    make wasm_debug      - Compilar a WebAssembly (Debug) sin desplegar"
	@echo ""
	@echo "  Otros:"
	@echo "    make show_version    - Mostrar version actual ($(VERSION))"
	@echo "    make help            - Mostrar esta ayuda"

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