VERSION ?= 0.1.0

# -H windowsgui suppresses the console window that would otherwise sit behind
# the tray icon. -s -w strips the symbol table and DWARF; nothing here needs a
# Go stack trace off a customer's laptop, and it roughly halves the binary.
LDFLAGS := -s -w -H windowsgui -X main.version=$(VERSION)

# Go is installed at ~/.local/go on this box and deliberately kept off PATH, so
# prefer that toolchain and fall back to whatever `go` is in PATH elsewhere.
GO ?= $(shell test -x $(HOME)/.local/go/bin/go && echo $(HOME)/.local/go/bin/go || echo go)

# Pinned and run through `go run` so CI needs no separate install step.
GOVERSIONINFO ?= $(GO) run github.com/josephspurrier/goversioninfo/cmd/goversioninfo@v1.4.1

SYSO := cmd/ipswap/resource_windows.syso

.PHONY: build syso test vet check dist sums installer clean help

help: ## List targets
	@grep -hE '^[a-zA-Z_-]+:.*?## ' $(MAKEFILE_LIST) | awk 'BEGIN{FS=":.*?## "}{printf "  %-14s %s\n", $$1, $$2}'

# ipswap is pure Go with no cgo anywhere, which is the whole reason the tray is
# fyne.io/systray and the dialogs are raw user32 rather than a GUI toolkit:
# `GOOS=windows go build` cross-compiles straight from Linux, no Wine, no
# mingw, no fyne-cross.
build: syso ## Cross-compile bin/ipswap.exe from any host
	@mkdir -p bin
	GOOS=windows GOARCH=amd64 $(GO) build -trimpath -ldflags "$(LDFLAGS)" -o bin/ipswap.exe ./cmd/ipswap

# The .syso carries the icon, the version resource and — the part that matters
# — the manifest that asks for asInvoker and per-monitor DPI. A plain `go
# build` with no .syso produces a binary with the generic executable icon and
# the default (unaware, asInvoker-by-omission) manifest.
#
# -64 is not optional: goversioninfo emits a 386 object by default, and linking
# that into an amd64 build fails with "unknown relocation type 7".
syso: ## Generate the Windows resource object
	cd cmd/ipswap && $(GOVERSIONINFO) \
		-64 \
		-o resource_windows.syso \
		-platform-specific=false \
		versioninfo.json

test: ## Run tests
	$(GO) test ./...

vet: ## Run go vet for both targets
	$(GO) vet ./...
	GOOS=windows GOARCH=amd64 $(GO) vet ./...

# The Windows-only files (netsh, user32, the registry) are the bulk of the
# risk, and a Linux `go build` never looks at them. This is the cheap way to
# keep them compiling.
check: test vet ## Typecheck both targets and run tests
	GOOS=windows GOARCH=amd64 $(GO) build ./...

dist: build sums ## Build the release artifacts into dist/
	@echo "dist/ contains:" && ls -1 dist

# Inno Setup is a Windows tool. On Windows use the ISCC on PATH; on Linux it
# runs perfectly well under wine, which is why this looks for both. Note that
# the installer is the ONLY part of the build that wants wine — the .exe itself
# still cross-compiles natively, so CI never needs it.
ISCC ?= $(shell command -v iscc 2>/dev/null || command -v ISCC 2>/dev/null)

installer: build ## Compile Output/ipswap-$(VERSION)-setup.exe (needs Inno Setup 6)
ifeq ($(ISCC),)
	@echo "Inno Setup not found."; \
	echo "  Windows: install Inno Setup 6 and put ISCC.exe on PATH"; \
	echo "  Linux:   apt install wine && download innosetup-6.x.exe, then"; \
	echo "           make installer ISCC='wine $$HOME/.wine/drive_c/Program Files (x86)/Inno Setup 6/ISCC.exe'"; \
	exit 1
else
	$(ISCC) /DAppVersion=$(VERSION) Inno-compile.iss
	@echo "built Output/ipswap-$(VERSION)-setup.exe"
endif

sums: ## Write dist/SHA256SUMS for the built binary
	@mkdir -p dist
	@cp bin/ipswap.exe dist/ipswap.exe
	cd dist && sha256sum ipswap.exe > SHA256SUMS
	@cat dist/SHA256SUMS

clean: ## Remove build artifacts
	rm -rf bin dist Output $(SYSO)
