# ==============================================================================
# DIRECTORIES
# ==============================================================================
DIR_ROOT       := $(dir $(abspath $(MAKEFILE_LIST)))

# ==============================================================================
# TARGET NAMES
# ==============================================================================
TARGET_NAME    := coffee_crisis_arcade_edition
ifeq ($(OS),Windows_NT)
    TARGET_FILE := $(DIR_ROOT)$(TARGET_NAME).exe
else
    TARGET_FILE := $(DIR_ROOT)$(TARGET_NAME)
endif
APP_NAME       := Coffee Crisis Arcade Edition
DIST_DIR       := dist
RELEASE_FOLDER := dist/_tmp
RELEASE_FILE   := $(RELEASE_FOLDER)/$(TARGET_NAME)
RESOURCE_FILE  := release/windows/coffee.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 (extraída de defines.hpp)
# ==============================================================================
ifeq ($(OS),Windows_NT)
    VERSION := $(shell powershell -Command "(Select-String -Path 'source/utils/defines.hpp' -Pattern 'constexpr const char\* VERSION = \"(.+?)\"').Matches.Groups[1].Value")
else
    VERSION := $(shell grep 'constexpr const char\* VERSION' source/utils/defines.hpp | sed -E 's/.*VERSION = "([^"]+)".*/\1/')
endif

# Hash del commit actual, computado en el host. Se pasa a CMake via -DGIT_HASH
# para que el build en docker/emscripten no falle por "dubious ownership" de Git.
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)
# ==============================================================================
ifeq ($(OS),Windows_NT)
    SHELL := cmd.exe
endif

# ==============================================================================
# WINDOWS-SPECIFIC VARIABLES
# ==============================================================================
ifeq ($(OS),Windows_NT)
    WIN_TARGET_FILE    := $(DIR_ROOT)$(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
	@cmake --build build

debug:
	@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Debug
	@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

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

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

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

# Compila con cmake
	@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release
	@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 la carpeta 'config' y el archivo 'resources.pack'
	@powershell -Command "Copy-Item -Path 'config' -Destination '$(RELEASE_FOLDER)' -recurse -Force"
	@powershell -Command "Copy-Item -Path 'resources.pack' -Destination '$(RELEASE_FOLDER)'"

# Copia los ficheros que estan en la raíz del proyecto
	@powershell -Command "Copy-Item 'LICENSE' -Destination '$(RELEASE_FOLDER)'"
	@powershell -Command "Copy-Item 'README.md' -Destination '$(RELEASE_FOLDER)'"
	@powershell -Command "Copy-Item 'release\windows\dll\*.dll' -Destination '$(RELEASE_FOLDER)'"
	@powershell -Command "Copy-Item -Path '$(TARGET_FILE)' -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:
	@$(MAKE) 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 de distribución y la carpeta temporal con las carpetas obligatorias para una app macOS
	$(MKDIR) "$(DIST_DIR)"
	$(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 -R config "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
	cp resources.pack "$(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 \
	   && 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
	@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:
	@$(MAKE) pack
	@echo "Creando release para Linux - Version: $(VERSION)"

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

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

# Copia ficheros
	cp -R config "$(RELEASE_FOLDER)"
	cp resources.pack "$(RELEASE_FOLDER)"
	cp LICENSE "$(RELEASE_FOLDER)"
	cp README.md "$(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) ($(GIT_HASH))"
	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/coffee-crisis-arcade-edition/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) ($(GIT_HASH))"
	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/"

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

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

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

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

cppcheck:
	@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release
	@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
# ==============================================================================
show_version:
	@echo "Version actual: $(VERSION)"

help:
	@echo "Makefile para Coffee Crisis Arcade Edition"
	@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 "    make wasm                - Crear build WebAssembly (requiere Docker) en dist/wasm"
	@echo "    make wasm_debug          - Build WebAssembly Debug local (sin deploy)"
	@echo ""
	@echo "  Herramientas:"
	@echo "    make compile_shaders     - Compilar shaders SPIR-V"
	@echo "    make pack                - Empaquetar recursos a resources.pack"
	@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 "  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 pack compile_shaders format format-check tidy tidy-fix cppcheck controllerdb show_version help
