# Requires
# · http://fossil.include-once.org/versionnum/

SHELL   := /bin/bash #(for brace expansion)
.DEFAULT_GOAL := all
NAME    := streamtuner2
VERSION := $(shell if command -v version >/dev/null 2>&1; then version get:plugin st2.py; else sed -n 's/^# version: //p' st2.py | head -n 1; fi || echo 2.2dev)
DEST    := /usr/share/streamtuner2
DOCS    := /usr/share/doc/streamtuner2
INST    := install -m 644
PYTHON  ?= python3
DEB_OUTDIR ?= DEBS
RPM_OUTDIR ?= RPMS
OBS_OUTDIR ?= OBS
SRC_OUTDIR ?= $(DEB_OUTDIR)
DSC_OUTDIR ?= $(DEB_OUTDIR)
ROOT_PY := action.py ahttp.py cli.py config.py diagnostics.py logo.py lsplug.py pluginconf.py pq.py recording.py st2.py uikit.py
PACKAGING_PY := packaging/__init__.py packaging/contrib_audit.py packaging/build_native_source.py packaging/build_pyz.py packaging/build_binary_deb.py packaging/build_binary_rpm.py packaging/build_obs_source.py packaging/publish_gitlab_release_assets.py packaging/trigger_obs_runservice.py packaging/bump_version.py
TEST_PY := $(ROOT_PY) $(PACKAGING_PY) channels/*.py bundle/*.py contrib/*.py
SRC_TARBALL := $(SRC_OUTDIR)/$(NAME)_$(VERSION).tar.xz
DSC_FILE := $(DSC_OUTDIR)/$(NAME).dsc
BUILDINFO_FILE := $(DSC_OUTDIR)/$(NAME).source.buildinfo
CHANGES_FILE := $(DSC_OUTDIR)/$(NAME).source.changes

# targets
.PHONY:	all help usage pack gtk3 glade docs ver clean check-deb-tools check-rpm-tools unsupported-bundle-targets xpm deb rpm tar exe arch osxpkg pyz zip dsc src obs-export bump-version test verify verify-src verify-packages check upload install st2 run yelp chm
all:	gtk3 ## Refresh the compressed GTK builder file (default lightweight target)
help: ## Show project targets and output directories
	@echo "Project targets for $(NAME) (use 'make help'; 'make --help' still shows GNU Make flags):"
	@awk 'BEGIN {FS = ":.*## "}; /^[[:alnum:]_.-]+:.*## / {printf "  %-18s %s\n", $$1, $$2}' $(MAKEFILE_LIST)
	@echo
	@printf "  %-18s %s\n" "DEB_OUTDIR" "$(DEB_OUTDIR)"
	@printf "  %-18s %s\n" "RPM_OUTDIR" "$(RPM_OUTDIR)"
	@printf "  %-18s %s\n" "OBS_OUTDIR" "$(OBS_OUTDIR)"
	@printf "  %-18s %s\n" "SRC_OUTDIR" "$(SRC_OUTDIR)"
	@printf "  %-18s %s\n" "DSC_OUTDIR" "$(DSC_OUTDIR)"
usage: help ## Alias for help
pack: pyz src deb rpm ## Build the supported package outputs
gtk3: ## Regenerate gtk3.xml.gz when gtk3.xml exists, otherwise validate the checked-in archive
	@if [ -f gtk3.xml ]; then \
		gzip -c9 < gtk3.xml > gtk3.xml.gz; \
	else \
		test -f gtk3.xml.gz || { echo "Missing gtk3.xml.gz"; exit 1; }; \
	fi
zip:	pyz ## Alias for pyz
print-%:
	@echo $*=$($*)


# Convert between internal GtkBuilder-gzipped file and uncompressed xml
glade: ## Open gtk3.xml in Glade and refresh gtk3.xml.gz afterwards
	gzip -dc > gtk3.xml < gtk3.xml.gz
	glade gtk3.xml 2>/dev/null
	gzip -c9 < gtk3.xml > gtk3.xml.gz

# Prepare packaging
docs: ## Placeholder for documentation prep hooks
ver:	## Refresh PKG-INFO from st2.py version metadata
	@if command -v version >/dev/null 2>&1; then \
		version get:plugin st2.py write:control PKG-INFO; \
	else \
		printf '%s\n' \
			'Metadata-Version: 1.0' \
			'Name: streamtuner2' \
			'Version: $(VERSION)' \
			'Summary: Streamtuner2 is an internet radio browser' \
			'Home-page: http://fossil.include-once.org/streamtuner2/' \
			'Author: Mario Salzer' \
			'Author-email: mario@include-once.org' \
			'License: Public Domain' \
			'Description: Streamtuner2 is an internet radio browser' \
			'Platform: ALL' \
			'Keywords: internet-radio, python, streaming, audio' \
			> PKG-INFO; \
			echo 'Wrote PKG-INFO without versionnum tool.'; \
	fi
clean: ## Remove local Python cache files
	rm -f *.pyc */*.pyc
	rm -rf __pycache__ */__pycache__

check-deb-tools: ## Verify Debian native packaging tools are installed
	@command -v dpkg-buildpackage >/dev/null 2>&1 || { \
		echo "Missing build dependency: dpkg-buildpackage"; \
		exit 127; \
	}
	@command -v dh >/dev/null 2>&1 || { \
		echo "Missing build dependency: debhelper/dh"; \
		exit 127; \
	}
	@command -v dh_python3 >/dev/null 2>&1 || { \
		echo "Missing build dependency: dh-python/dh_python3"; \
		exit 127; \
	}
	@command -v fakeroot >/dev/null 2>&1 || { \
		echo "Missing build dependency: fakeroot"; \
		exit 127; \
	}

check-rpm-tools: ## Verify RPM native packaging tools are installed
	@command -v rpmbuild >/dev/null 2>&1 || { \
		echo "Missing build dependency: rpmbuild"; \
		exit 127; \
	}

unsupported-bundle-targets:
	@echo "This legacy xpm-based bundle target is no longer supported."
	@echo "Supported package targets: make deb, make rpm, make src, make obs-export, make pyz"
	@exit 2

deb: all check-deb-tools ## Build the native Debian .deb package into DEBS/
	mkdir -p "$(DEB_OUTDIR)"
	$(PYTHON) packaging/build_binary_deb.py --output-dir "$(DEB_OUTDIR)"
rpm: all check-rpm-tools ## Build the native RPM package into RPMS/
	mkdir -p "$(RPM_OUTDIR)"
	$(PYTHON) packaging/build_binary_rpm.py --output-dir "$(RPM_OUTDIR)"
tar: unsupported-bundle-targets ## Unsupported legacy xpm bundle target
exe: unsupported-bundle-targets ## Unsupported legacy xpm bundle target
arch: unsupported-bundle-targets ## Unsupported legacy xpm bundle target
osxpkg: unsupported-bundle-targets ## Unsupported legacy xpm bundle target
xpm: unsupported-bundle-targets ## Unsupported legacy xpm bundle target
pyz: gtk3 ## Build the standalone .pyz archive
	$(PYTHON) packaging/build_pyz.py --output "$(NAME)-$(VERSION).pyz"
dsc: src ## Alias for src
src: gtk3 ## Build native Debian source artifacts into DEBS/
	mkdir -p "$(SRC_OUTDIR)" "$(DSC_OUTDIR)"
	$(PYTHON) packaging/build_native_source.py --tar-output-dir "$(SRC_OUTDIR)" --dsc-output-dir "$(DSC_OUTDIR)"
obs-export: gtk3 ## Build the OBS-ready flat source set into OBS/
	mkdir -p "$(OBS_OUTDIR)"
	$(PYTHON) packaging/build_obs_source.py --output-dir "$(OBS_OUTDIR)"
bump-version: ## Synchronize changelog, RPM spec, and st2.py version metadata
	@if [ "$(origin VERSION)" = "file" ]; then \
		$(PYTHON) packaging/bump_version.py; \
	else \
		$(PYTHON) packaging/bump_version.py "$(VERSION)"; \
	fi

test: ## Run basic offline checks for runtime and packaging helpers
	gzip -t gtk3.xml.gz
	$(PYTHON) -m py_compile $(TEST_PY)
	$(PYTHON) -m unittest discover -s tests -t . -p 'test_*.py'

verify-src: src ## Validate the generated native Debian source artifacts
	test -f "$(SRC_TARBALL)"
	test -f "$(DSC_FILE)"
	test -f "$(BUILDINFO_FILE)"
	test -f "$(CHANGES_FILE)"
	grep -q "Format: 3.0 (native)" "$(DSC_FILE)"
	grep -q "$(notdir $(SRC_TARBALL))" "$(CHANGES_FILE)"

verify-packages: ## Inspect final .deb/.rpm artifacts if present in DEBS/ and RPMS/
	@set -e; \
	if ls "$(DEB_OUTDIR)"/*.deb >/dev/null 2>&1; then \
		command -v dpkg-deb >/dev/null 2>&1 || { echo "Missing tool: dpkg-deb"; exit 127; }; \
		echo "Inspecting Debian package(s) in $(DEB_OUTDIR)/"; \
		dpkg-deb -I "$(DEB_OUTDIR)"/*.deb >/dev/null; \
		dpkg-deb -c "$(DEB_OUTDIR)"/*.deb >/dev/null; \
	else \
		echo "No .deb package found in $(DEB_OUTDIR)/; skipping."; \
	fi; \
	first_rpm=$$(find "$(RPM_OUTDIR)" -type f -name '*.rpm' -print -quit 2>/dev/null); \
	if [ -n "$$first_rpm" ]; then \
		command -v rpm >/dev/null 2>&1 || { echo "Missing tool: rpm"; exit 127; }; \
		echo "Inspecting RPM package $$first_rpm"; \
		rpm -qpil "$$first_rpm" >/dev/null; \
	else \
		echo "No .rpm package found in $(RPM_OUTDIR)/; skipping."; \
	fi

verify: test verify-src verify-packages ## Run the basic offline validation workflow

snap:	pyz
	cp streamtuner2-*.pyz streamtuner2.pyz
	zip snapcraft.zip streamtuner2.pyz
	version read ./st2.py write:_raw_ dev/snapcraft.yaml
	snapcraft 

# test .deb contents
check: verify-packages ## Alias for package inspection
	
upload: ## Upload built bundle artifacts to release mirrors
	scp *.{deb,rpm,pyz} io:st2/
	scp *.{deb,rpm,pyz} sf:/home/frs/project/streamtuner2/

# manual installation
install: ## Install the application into the current system prefix
	mkdir	-p			$(DEST)/channels
	mkdir	-p			$(DEST)/contrib
	mkdir	-p			$(DOCS)/streamtuner2/help/img
	mkdir	-p			$(DEST)/packaging
	install -m 755	st2.py		/usr/bin/streamtuner2
	$(INST)		*py		-t $(DEST)
	$(INST)		gtk3*		-t $(DEST)
	$(INST)		channels/*py	-t $(DEST)/channels
	$(INST)		contrib/*py	-t $(DEST)/contrib
	$(INST)		packaging/__init__.py packaging/contrib_audit.py	-t $(DEST)/packaging
	$(INST)		help/*page	-t $(DOCS)/streamtuner2/help
	$(INST)		help/img/*	-t $(DOCS)/streamtuner2/help/img
	$(INST)		CREDITS		-t $(DEST)
	$(INST)		README.md	-t $(DOCS)
	$(INST)		*.desktop	-t /usr/share/applications/
	$(INST)		icon.png	/usr/share/pixmaps/streamtuner2.png
	$(INST)		help/str*2.1	-t /usr/share/man/man1/
	python3 -m pip install requests pyquery lxml pillow pyxdg yt-dlp

# start locally
st2: run ## Alias for run
run: ## Launch streamtuner2 locally with debug output
	#MALLOC_CHECK_=2 PYTHONVERBOSE=2
	python -B  ./st2.py -D  -e dev_faulthandler

yelp: ## Open the Mallard help locally and rebuild HTML help output
	yelp help/index.page 2>/dev/null &
	(cd help/html ; yelp-build html ..)

chm: ## Rebuild the CHM help inputs from Mallard pages
	cd help         # mallard → epub → docbook → chm
	yelp-build epub
	mv index.epub help.epub
	pandoc help.epub -t docbook > help.docbook
	rm help.epub
	#lxy...?
