# **************************************************************************
# * (C)opyright 2026         by Ruben Carlo Benante                        *
# *                                                                        *
# * This program is free software; you can redistribute it and/or modify   *
# *  it under the terms of the GNU General Public License as published by  *
# *  the Free Software Foundation, either version 3 of the License, or     *
# *  (at your option) any later version.                                   *
# *                                                                        *
# * This program is distributed in the hope that it will be useful,        *
# *  but WITHOUT ANY WARRANTY; without even the implied warranty of        *
# *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
# *  GNU General Public License for more details.                          *
# *                                                                        *
# * You should have received a copy of the GNU General Public License      *
# *  along with this program.  If not, see http://www.gnu.org/licenses/.   *
# *                                                                        *
# * Contact author at:                                                     *
# *  Ruben Carlo Benante                                                   *
# *  rcb@beco.cc                                                           *
# **************************************************************************

# Makefile for logsdu - build the extension for Firefox and Chrome.
#
# Usage:
#   make            # typecheck and bundle for Firefox into build/
#   make chrome     # same, but with Chrome's manifest, into build/
#   make test       # run the unit tests
#   make smoke      # check the background bundle works as a service worker
#   make xpi        # package the Firefox build  -> dist/logsdu-<version>.xpi
#   make crx        # package the Chrome build   -> dist/logsdu-<version>-chrome.zip
#   make packages   # both of the above
#   make clean      # remove build/ and dist/
#
# build/ holds the unpacked extension and is regenerated from scratch; dist/
# holds the packages meant to be published, and is kept out of build/ so that
# packaging never tries to include its own output.
#
# Dependencies are installed with pnpm, never npm:
#   corepack pnpm install
#
# Load the unpacked build while developing:
#   Firefox  about:debugging -> This Firefox -> Load Temporary Add-on ->
#            build/manifest.json          (dropped when Firefox restarts)
#   Chrome   chrome://extensions -> Developer mode -> Load unpacked -> build/
#
# Publishing:
#   Firefox  upload dist/*.xpi at addons.mozilla.org
#   Chrome   upload dist/*-chrome.zip at chrome.google.com/webstore/devconsole

EXT_ID := logsdu
VERSION := $(shell node -p "require('./package.json').version")
DIST := dist
XPI := $(DIST)/$(EXT_ID)-$(VERSION).xpi
CRX := $(DIST)/$(EXT_ID)-$(VERSION)-chrome.zip

.PHONY: all build chrome test smoke xpi crx packages clean check-deps

all: build

# Unit tests for the pure logic: the input formatters and the decision that
# says whether a page load may press "Entrar". Run straight through Node's
# built-in runner and type stripping, so there is no test framework to install.
test:
	node --test "src/**/*.test.ts"

# Runs the built background bundle in a service-worker-shaped sandbox, which
# is where a Chrome-only breakage would otherwise hide until runtime.
smoke: build
	node tools/sw-smoke.mjs

# Call the local toolchain directly, so this works regardless of how pnpm is
# provided (corepack vs standalone). Run "corepack pnpm install" first.
build: check-deps
	node_modules/.bin/tsc -noEmit -skipLibCheck
	node esbuild.config.mjs production

# The same sources with Chrome's manifest. Firefox and Chrome disagree on the
# background key and on the gecko block, so the manifest is generated per
# target rather than forked.
chrome: check-deps
	node_modules/.bin/tsc -noEmit -skipLibCheck
	TARGET=chrome node esbuild.config.mjs production
	@echo "Chrome build in build/ -- chrome://extensions -> Developer mode -> Load unpacked."

# An .xpi is just a zip of the extension directory, with the manifest at the
# top level rather than inside a wrapper folder.
xpi: build
	@mkdir -p $(DIST)
	rm -f $(XPI)
	cd build && zip -qr ../$(XPI) .
	@echo
	@echo "Built: $(CURDIR)/$(XPI)"
	@echo
	@echo "This file is UNSIGNED. Two ways to use it:"
	@echo
	@echo "  Publish -- upload it at addons.mozilla.org/developers/addon/submit/"
	@echo "    Listed add-ons are signed once review approves them; unlisted"
	@echo "    ones are signed straight away."
	@echo
	@echo "  Install locally -- only on ESR, Developer Edition or Nightly:"
	@echo "    1. about:config -> xpinstall.signatures.required = false"
	@echo "    2. about:addons -> gear icon -> Install Add-on From File"
	@echo "    3. paste this path into the file picker:"
	@echo "       $(CURDIR)/$(XPI)"
	@echo

# The Chrome Web Store takes a plain zip, and does the packing into .crx itself.
crx: chrome
	@mkdir -p $(DIST)
	rm -f $(CRX)
	cd build && zip -qr ../$(CRX) .
	@echo
	@echo "Built: $(CURDIR)/$(CRX)"
	@echo "Upload it at chrome.google.com/webstore/devconsole"
	@echo

# Both packages. The Firefox build runs last so build/ is left in the state
# the development instructions assume.
packages: crx xpi

clean:
	rm -rf build $(DIST)

# Fail with a useful message rather than a confusing "tsc: not found".
check-deps:
	@test -x node_modules/.bin/tsc || { \
		echo "ERROR: dependencies are not installed."; \
		echo "Run: corepack pnpm install   (do NOT use npm install in this tree)"; \
		exit 1; \
	}
