PROJECT  := orni
BUILDDIR := build

# Detecció de plataforma. En Windows CMake defaulteja a "NMake Makefiles"
# (que requereix Visual Studio); forcem MinGW Makefiles per usar el g++ de
# MinGW. nproc tampoc existeix en cmd.exe → fem servir NUMBER_OF_PROCESSORS.
ifeq ($(OS),Windows_NT)
    ifneq ($(MSYSTEM),)
        NULDEV := /dev/null
    else
        NULDEV := NUL
    endif
    JOBS      ?= $(NUMBER_OF_PROCESSORS)
    HAS_NINJA := $(shell ninja --version 2>$(NULDEV))
    ifneq ($(HAS_NINJA),)
        CMAKE_GEN := -G "Ninja"
    else
        CMAKE_GEN := -G "MinGW Makefiles"
    endif
else
    NULDEV    := /dev/null
    JOBS      ?= $(shell nproc 2>/dev/null || echo 4)
    HAS_NINJA := $(shell ninja --version 2>/dev/null)
    ifneq ($(HAS_NINJA),)
        CMAKE_GEN := -G "Ninja"
    else
        CMAKE_GEN :=
    endif
endif

# VERSION (única font de veritat: CMakeLists.txt project(...) VERSION ...).
# Lazy (=): només es calcula quan s'invoca un target que la usa.
ifeq ($(OS),Windows_NT)
    VERSION = v$(shell powershell -Command "(Select-String -Path 'CMakeLists.txt' -Pattern 'project.*VERSION\s+([0-9.]+)').Matches.Groups[1].Value")
else
    VERSION = v$(shell grep '^project' CMakeLists.txt | sed -E 's/.*VERSION[[:space:]]+([0-9.]+).*/\1/')
endif

# GIT_HASH calculat al host i passat a CMake (evita problemes si CMake corre en
# entorns sense accés a git).
GIT_HASH := $(shell git rev-parse --short=7 HEAD 2>$(NULDEV))
ifeq ($(GIT_HASH),)
    GIT_HASH := unknown
endif

CMAKE_DEFS := -DGIT_HASH=$(GIT_HASH)

# ==============================================================================
# RELEASE — variables d'empaquetat per distribució
# ==============================================================================
APP_NAME       := Orni Attack
DIST_DIR       := dist
RELEASE_FOLDER := $(DIST_DIR)/_tmp
TARGET_FILE    := $(BUILDDIR)/$(PROJECT)
RELEASE_FILE   := $(RELEASE_FOLDER)/$(PROJECT)

# Noms dels artefactes finals (amb VERSION i PROJECT)
WINDOWS_RELEASE             := $(DIST_DIR)/$(PROJECT)-$(VERSION)-win32-x64.zip
MACOS_APPLE_SILICON_RELEASE := $(DIST_DIR)/$(PROJECT)-$(VERSION)-macos-apple-silicon.dmg
LINUX_RELEASE               := $(DIST_DIR)/$(PROJECT)-$(VERSION)-linux.tar.gz

# Variables específiques de Windows (PowerShell). El subst escapa apòstrofs.
ifeq ($(OS),Windows_NT)
    WIN_TARGET_FILE     := $(BUILDDIR)/$(APP_NAME)
    WIN_RELEASE_FILE    := $(RELEASE_FOLDER)/$(APP_NAME)
    WIN_RELEASE_FILE_PS := $(subst ','',$(WIN_RELEASE_FILE))
    UNAME_S             :=
else
    WIN_TARGET_FILE     := $(TARGET_FILE)
    WIN_RELEASE_FILE    := $(RELEASE_FILE)
    WIN_RELEASE_FILE_PS := $(WIN_RELEASE_FILE)
    UNAME_S             := $(shell uname -s)
endif

# Helpers cross-platform.
ifeq ($(OS),Windows_NT)
    RMFILE := del /Q
    RMDIR  := rmdir /S /Q
    MKDIR  := mkdir
else
    RMFILE := rm -f
    RMDIR  := rm -rdf
    MKDIR  := mkdir -p
endif

.PHONY: all debug release _windows-release _macos-release _linux-release \
        run run-debug clean rebuild show-version pack controllerdb \
        format format-check tidy tidy-fix cppcheck hooks-install help

# Còpia del gamecontrollerdb.txt (si existeix) al directori de build, perquè
# director.cpp el resolgui via resource_base = directori de l'executable.
# Silenciós si el fitxer no existeix (l'usuari encara no ha fet `make controllerdb`).
ifeq ($(OS),Windows_NT)
    CP_CONTROLLERDB = @powershell -Command "if (Test-Path 'gamecontrollerdb.txt') { Copy-Item 'gamecontrollerdb.txt' -Destination '$(BUILDDIR)' -Force }"
else
    CP_CONTROLLERDB = @if [ -f gamecontrollerdb.txt ]; then cp gamecontrollerdb.txt $(BUILDDIR)/; fi
endif

# ==============================================================================
# COMPILACIÓ
# ==============================================================================
#   make           → Release (binari d'ús normal)
#   make debug     → Debug
#   make release   → Release + empaquetat per a distribució (zip/dmg/tar.gz segons SO)
# ==============================================================================

all:
	@cmake -S . -B $(BUILDDIR) $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Release $(CMAKE_DEFS)
	@cmake --build $(BUILDDIR) -j$(JOBS)
	$(CP_CONTROLLERDB)

debug:
	@cmake -S . -B $(BUILDDIR) $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Debug $(CMAKE_DEFS)
	@cmake --build $(BUILDDIR) -j$(JOBS)
	$(CP_CONTROLLERDB)

run: all
	@./$(BUILDDIR)/$(PROJECT)

run-debug: debug
	@./$(BUILDDIR)/$(PROJECT)

# Release + empaquetat: detecta el SO i delega al sub-target corresponent.
release:
ifeq ($(OS),Windows_NT)
	@"$(MAKE)" _windows-release
else
ifeq ($(UNAME_S),Darwin)
	@$(MAKE) _macos-release
else
	@$(MAKE) _linux-release
endif
endif

# ==============================================================================
# RELEASE — Linux (.tar.gz)
# ==============================================================================
_linux-release:
	@echo "Creando release para Linux - Version: $(VERSION)"

# Compila Release (genera resources.pack i binari)
	@cmake -S . -B $(BUILDDIR) $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Release $(CMAKE_DEFS)
	@cmake --build $(BUILDDIR) -j$(JOBS)

# Recrea la carpeta temporal
	@$(MKDIR) "$(DIST_DIR)" 2>/dev/null || true
	@$(RMDIR) "$(RELEASE_FOLDER)" 2>/dev/null || true
	$(MKDIR) "$(RELEASE_FOLDER)"

# Còpia de fitxers
	cp $(BUILDDIR)/resources.pack "$(RELEASE_FOLDER)"
	cp gamecontrollerdb.txt "$(RELEASE_FOLDER)"
	cp README.md "$(RELEASE_FOLDER)"
	@[ -f LICENSE ] && cp LICENSE "$(RELEASE_FOLDER)" || true
	cp "$(TARGET_FILE)" "$(RELEASE_FILE)"
	strip -s -R .comment -R .gnu.version "$(RELEASE_FILE)" --strip-unneeded

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

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

# ==============================================================================
# RELEASE — Windows (.zip)
# ==============================================================================
_windows-release:
	@echo off
	@echo Creando release para Windows - Version: $(VERSION)

	@cmake -S . -B $(BUILDDIR) $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Release $(CMAKE_DEFS)
	@cmake --build $(BUILDDIR) -j$(JOBS)

	@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}"

	@powershell -Command "Copy-Item -Path '$(BUILDDIR)/resources.pack' -Destination '$(RELEASE_FOLDER)'"
	@powershell -Command "Copy-Item 'gamecontrollerdb.txt' -Destination '$(RELEASE_FOLDER)'"
	@powershell -Command "if (Test-Path 'LICENSE') { Copy-Item 'LICENSE' -Destination '$(RELEASE_FOLDER)' }"
	@powershell -Command "Copy-Item 'README.md' -Destination '$(RELEASE_FOLDER)'"
	@powershell -Command "if (Test-Path 'release\windows\dll') { 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

	@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)

	@powershell -Command "if (Test-Path '$(RELEASE_FOLDER)') {Remove-Item '$(RELEASE_FOLDER)' -Recurse -Force}"

# ==============================================================================
# RELEASE — macOS (.dmg per Apple Silicon)
# ==============================================================================
_macos-release:
	@echo "Creando release para macOS - Version: $(VERSION)"

# Verificar/instal·lar create-dmg si cal
	@which create-dmg > /dev/null || (echo "Instalando create-dmg..." && brew install create-dmg)

# Compila la versió Apple Silicon
	@cmake -S . -B $(BUILDDIR)/arm $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Release \
		-DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 \
		-DMACOS_BUNDLE=ON $(CMAKE_DEFS)
	@cmake --build $(BUILDDIR)/arm -j$(JOBS)

# Neteja artefactes anteriors
	@$(MKDIR) "$(DIST_DIR)" 2>/dev/null || true
	$(RMDIR) "$(RELEASE_FOLDER)" 2>/dev/null || true
	$(RMFILE) "$(DIST_DIR)"/rw.* 2>/dev/null || true
	$(RMFILE) "$(MACOS_APPLE_SILICON_RELEASE)"

# Crea l'estructura del bundle .app
	$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks"
	$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS"
	$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"

# Còpia de recursos i metadades del bundle
	cp $(BUILDDIR)/arm/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/icon.icns "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
	cp release/macos/Info.plist "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents"
	@[ -f LICENSE ] && cp LICENSE "$(RELEASE_FOLDER)" || true
	cp README.md "$(RELEASE_FOLDER)"

# Recreate framework symlinks (Versions/Current i top-level)
	@cd "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks/SDL3.framework" && \
		rm -f SDL3 Headers Resources && \
		ln -s Versions/Current/SDL3 SDL3 && \
		ln -s Versions/Current/Headers Headers && \
		ln -s Versions/Current/Resources Resources
	@cd "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks/SDL3.framework/Versions" && \
		rm -f Current && ln -s A Current

# Actualitza Info.plist amb VERSION i metadades
	@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"; \
	sed -i '' '/<key>CFBundleExecutable<\/key>/{n;s|<string>.*</string>|<string>$(PROJECT)</string>|;}' "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist"; \
	sed -i '' '/<key>CFBundleName<\/key>/{n;s|<string>.*</string>|<string>$(APP_NAME)</string>|;}' "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist"; \
	sed -i '' '/<key>CFBundleDisplayName<\/key>/{n;s|<string>.*</string>|<string>$(APP_NAME)</string>|;}' "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist"

# Còpia del binari al bundle
	cp "$(BUILDDIR)/arm/$(PROJECT)" "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS/$(PROJECT)"

# Firma ad-hoc del bundle
	codesign --deep --force --sign - --timestamp=none "$(RELEASE_FOLDER)/$(APP_NAME).app"

# Empaqueta el .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)"

# Neteja temporals
	$(RMDIR) "$(RELEASE_FOLDER)"
	$(RMDIR) $(BUILDDIR)/arm
	$(RMFILE) "$(DIST_DIR)"/rw.* 2>/dev/null || true

show-version:
	@echo "$(PROJECT) $(VERSION) ($(GIT_HASH))"

clean:
	@rm -rf $(BUILDDIR) $(DIST_DIR)

rebuild: clean all

# Empaqueta data/ a $(BUILDDIR)/resources.pack. Força un rebuild del pack encara
# que res no hagi canviat dins data/. L'empaquetat també es fa automàticament a
# cada `make`/`make debug` via el target CMake `resource_pack`.
pack:
	@cmake -S . -B $(BUILDDIR) $(CMAKE_GEN) $(CMAKE_DEFS)
	@cmake --build $(BUILDDIR) --target pack_resources
	@./$(BUILDDIR)/pack_resources data $(BUILDDIR)/resources.pack

# ==============================================================================
# DESCÀRREGA DE GAMECONTROLLERDB
# ==============================================================================
# Descarrega l'última versió de gamecontrollerdb.txt (mappings de gamepads
# mantinguts per la comunitat) a l'arrel del projecte. SDL el carrega via
# filesystem real (no dins resources.pack) i s'ha de copiar al costat del binari
# en cada build (gestionat per CP_CONTROLLERDB a `all`/`debug` i pels release targets).
controllerdb:
	@echo "Descargando gamecontrollerdb.txt..."
	curl -fsSL https://raw.githubusercontent.com/mdqinc/SDL_GameControllerDB/master/gamecontrollerdb.txt \
		-o gamecontrollerdb.txt
	@echo "gamecontrollerdb.txt actualizado"

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

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

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

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

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

# ==============================================================================
# GIT HOOKS
# ==============================================================================
hooks-install:
	@git config core.hooksPath .githooks
	@echo "Git hooks activats: $(shell pwd)/.githooks"

# ==============================================================================
# AJUDA
# ==============================================================================
help:
	@echo "Makefile per a $(PROJECT)"
	@echo ""
	@echo "  Compilació:"
	@echo "    make                     - Compilar amb cmake (Release)"
	@echo "    make debug               - Compilar amb cmake (Debug)"
	@echo ""
	@echo "  Execució:"
	@echo "    make run                 - Compilar (Release) i executar"
	@echo "    make run-debug           - Compilar (Debug) i executar"
	@echo ""
	@echo "  Release:"
	@echo "    make release             - Release + empaquetat (zip/dmg/tar.gz segons SO)"
	@echo ""
	@echo "  Recursos:"
	@echo "    make pack                - Empaquetar data/ a $(BUILDDIR)/resources.pack"
	@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 clean               - Esborrar $(BUILDDIR)/ i $(DIST_DIR)/"
	@echo "    make rebuild             - clean + all"
	@echo "    make show-version        - Mostrar versió"
	@echo "    make hooks-install       - Activar git hooks del projecte"
	@echo ""
	@echo "  Versió actual: $(VERSION) ($(GIT_HASH))"
