ASLFLAGS = -C -g map -L -s -u -P
P2BINFLAGS = -l 0

ASM_SOURCES = $(wildcard src/*.6502.asm)

# Get current version from Git tags
VERSION := $(shell git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
VERSION_NUM := $(VERSION:v%=%)

.PHONY: all clean asl-clean test build-pass run fceux-clean release-major release-minor release-patch tag-release package

all: build-pass

# Build the ASL assembler
vendor/asl/asl:
	@cp -f .asl-gitignore vendor/asl/.gitignore
	@cp -f .asl-Makefile.def vendor/asl/Makefile.def
	@cd vendor/asl && $(MAKE) -j$(shell nproc)

asl-clean:
	@cd vendor/asl && $(MAKE) clean

# Generate CHR ROM from tileset
chr.rom: tileset.gif gif2chr.py
	@./gif2chr.py tileset.gif chr.rom palette.bin

# Build test ROM
test/test.rom: test/test.6502.asm $(ASM_SOURCES) vendor/asl/asl
	@vendor/asl/asl $(ASLFLAGS) test/test.6502.asm
	@vendor/asl/p2bin $(P2BINFLAGS) test/test.p test/test.rom
	@./mem-usage.py test/test.map

test/test.hex: test/test.rom
	@hexdump -C test/test.rom > test/test.hex

# Build main ROM
starclear.nes: src/starclear.6502.asm $(ASM_SOURCES) chr.rom vendor/asl/asl
	@vendor/asl/asl $(ASLFLAGS) src/starclear.6502.asm
	@vendor/asl/p2bin $(P2BINFLAGS) src/starclear.p starclear.nes
	@./mem-usage.py src/starclear.map

starclear.hex: starclear.nes
	@hexdump -C starclear.nes > starclear.hex

# Run tests
test: test/test.rom test/test.hex
	@cd test && ./test.py

# Main build target
build-pass: chr.rom test/test.hex starclear.hex test
	@echo "=== BUILD PASS ==="

# Build the FCEUX emulator
vendor/fceux/build/src/fceux:
	@mkdir -p vendor/fceux/build
	@cd vendor/fceux/build && cmake .. && $(MAKE) -j$(shell nproc)

fceux-clean:
	@rm -rf vendor/fceux/build

# Run the game in emulator
run: starclear.nes vendor/fceux/build/src/fceux
	@vendor/fceux/build/src/fceux starclear.nes

# Clean generated files
clean:
	@rm -f chr.rom palette.bin
	@rm -f test/test.p test/test.rom test/test.hex test/test.i test/test.lst test/test.map
	@rm -f src/starclear.p src/starclear.map src/starclear.lst src/starclear.i starclear.nes starclear.hex
	@rm -rf dist
	@find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
	@find . -type f -name "*.pyc" -delete 2>/dev/null || true

release-major:
	@$(MAKE) tag-release BUMP=major

release-minor:
	@$(MAKE) tag-release BUMP=minor

release-patch:
	@$(MAKE) tag-release BUMP=patch

tag-release:
	@if ! git diff-index --quiet HEAD --; then \
		echo "Error: You have uncommitted changes. Commit or stash them first."; \
		git status --porcelain; \
		exit 1; \
	fi
	@current=$$(git describe --tags --abbrev=0 2>/dev/null | sed 's/v//') || current="0.0.0"; \
	major=$$(echo $$current | cut -d. -f1); \
	minor=$$(echo $$current | cut -d. -f2); \
	patch=$$(echo $$current | cut -d. -f3); \
	case $(BUMP) in \
		major) new="$$(($$major + 1)).0.0" ;; \
		minor) new="$$major.$$(($$minor + 1)).0" ;; \
		patch) new="$$major.$$minor.$$(($$patch + 1))" ;; \
		*) echo "Invalid bump type: $(BUMP)"; exit 1 ;; \
	esac; \
	echo "Bumping from v$$current to v$$new"; \
	if ! grep -q "^## \[$$new\]" CHANGELOG.md; then \
		echo "Error: CHANGELOG.md does not contain an entry for version $$new"; \
		echo "Please add a changelog entry before releasing."; \
		exit 1; \
	fi; \
	git tag -a "v$$new" -m "Release v$$new" && \
	echo "Successfully tagged v$$new"

package: build-pass
	@mkdir -p dist
	@# Check if repo is dirty (uncommitted changes) or not at expected tag
	@ACTUAL_VERSION=$(VERSION); \
	if [ -n "$$(git status --porcelain)" ] || [ "$$(git describe --exact-match --tags HEAD 2>/dev/null)" != "$(VERSION)" ]; then \
		ACTUAL_VERSION="$(VERSION)-dirty"; \
	fi; \
	echo "Packaging $$ACTUAL_VERSION..."; \
	mkdir -p dist/$$ACTUAL_VERSION; \
	cp starclear.nes dist/$$ACTUAL_VERSION/starclear-$$ACTUAL_VERSION.nes; \
	cp starclear.nes dist/starclear-latest.nes; \
	cp CHANGELOG.md dist/; \
	echo "Creating source archive..."; \
	git archive --format=zip --prefix=starclear-$$ACTUAL_VERSION/ HEAD -o dist/$$ACTUAL_VERSION/starclear-$$ACTUAL_VERSION-source.zip; \
	cp dist/$$ACTUAL_VERSION/starclear-$$ACTUAL_VERSION-source.zip dist/starclear-latest-source.zip; \
	echo "Generating latest.json..."; \
	echo "{" > dist/latest.json; \
	echo "  \"version\": \"$$ACTUAL_VERSION\"," >> dist/latest.json; \
	echo "  \"releaseDate\": \"$$(date +%Y-%m-%d)\"," >> dist/latest.json; \
	echo "  \"downloads\": [" >> dist/latest.json; \
	echo "    {" >> dist/latest.json; \
	echo "      \"path\": \"$$ACTUAL_VERSION/starclear-$$ACTUAL_VERSION.nes\"," >> dist/latest.json; \
	echo "      \"description\": \"NES ROM\"" >> dist/latest.json; \
	echo "    }," >> dist/latest.json; \
	echo "    {" >> dist/latest.json; \
	echo "      \"path\": \"$$ACTUAL_VERSION/starclear-$$ACTUAL_VERSION-source.zip\"," >> dist/latest.json; \
	echo "      \"description\": \"Source code archive\"" >> dist/latest.json; \
	echo "    }" >> dist/latest.json; \
	echo "  ]" >> dist/latest.json; \
	echo "}" >> dist/latest.json

deploy:
	rsync -av dist/ mddhosting:public_html/starclear-nes.git/dist/
