.PHONY: FORCE emblemscanner-release fetch fetch-quick sbs-quick train-quick verify

DATA_DIR ?= $(HOME)/emblem

IMAGE_TAG := $(shell git rev-parse --short HEAD)
IMAGE_REPO := registry.gitlab.com/euphon/themblem
IMAGE_REPO_PROD := registry.cn-shenzhen.aliyuncs.com/emblem/themblem
IMAGE := $(IMAGE_REPO):$(IMAGE_TAG)
IMAGE_PROD := $(IMAGE_REPO_PROD):$(IMAGE_TAG)

ifeq ($(shell uname), Darwin)
	BUILD_SHARED_LIBS := ON
else
	BUILD_SHARED_LIBS := OFF
endif

API_FILES = $(addprefix build/, $(shell find -L api -type f))

WEB_FILES = \
	$(addprefix build/, \
		$(shell find -L \
			web/dist \
			-type f)\
	)

SCRIPTS_FILES = \
	$(addprefix build/, \
		$(shell find -L \
			scripts \
			-type f \
			) \
	)

DATASET_FILES = \
	$(addprefix build/, \
		$(shell find -L \
			dataset \
			-name topleft-0518.jpeg \
			) \
	)

ALG_FILES = \
	$(addprefix build/, \
		$(shell find -L \
			alg/qrtool \
			alg/wechat_qrcode \
			alg/models/ \
			) \
	)

docker-build: build/Dockerfile build/requirements.txt \
		build/nginx.conf $(WEB_FILES) $(API_FILES) $(ALG_FILES) $(SCRIPTS_FILES) $(DATASET_FILES)
	find build
	docker build --network=host -t $(IMAGE) build

docker-push:
	docker push $(IMAGE)

docker-push-prod:
	docker tag $(IMAGE) $(IMAGE_PROD)
	docker push $(IMAGE_PROD)

docker-run:
	docker run -it --rm $(IMAGE)

web: FORCE
	cd web && npm run build
	mkdir -p build/web
	cp -r web/dist build/web/dist

build/Dockefile: FORCE
	mkdir -p build
	cp Dockerfile build/Dockerfile
	echo ENV EMBLEM_IMAGE=$(IMAGE) >> build/Dockerfile

build/%: %
	mkdir -p $(shell dirname $@)
	cp -a $^ $@

deploy-api-dev:
	./scripts/deploy.sh deploy/kubeconfig.dev $(IMAGE)

deploy-api-prod:
	./scripts/deploy.sh deploy/kubeconfig.themblem $(IMAGE_PROD)

test: FORCE
	cd api; ./manage.py migrate && ./manage.py test tests

fetch: FORCE
	cd emblem5 && uv run --with-requirements ../requirements.txt ./ai/fetch-scans.py --data-dir $(DATA_DIR)
	cd emblem5 && uv run --with-requirements ../requirements.txt ./ai/make-sbs.py --data-dir $(DATA_DIR)

fetch-quick: FORCE
	cd emblem5 && uv run --with-requirements ../requirements.txt ./ai/fetch-scans.py --data-dir $(DATA_DIR) --sample-rate 0.01

sbs: FORCE
	cd emblem5 && uv run --with-requirements ../requirements.txt ./ai/make-sbs.py --data-dir $(DATA_DIR)

train: FORCE
	cd emblem5 && uv run --with-requirements ../requirements.txt ./ai/train2.py --data-dir $(DATA_DIR) --epochs 30

train-quick: FORCE
	cd emblem5 && uv run --with-requirements ../requirements.txt ./ai/train2.py --data-dir $(DATA_DIR) --quick --epochs 2

browser: FORCE
	cd emblem5 && uv run --with-requirements ../requirements.txt streamlit run ./ai/browser.py -- --data-dir $(DATA_DIR)

verify: FORCE
	@if [ -z "$(SBS_IMG)" ]; then \
		echo "Error: SBS_IMG is required. Usage: make verify SBS_IMG=/path/to/sbs.jpg MODEL=/path/to/model.pt"; \
		exit 1; \
	fi
	@if [ -z "$(MODEL)" ]; then \
		echo "Error: MODEL is required. Usage: make verify SBS_IMG=/path/to/sbs.jpg MODEL=/path/to/model.pt"; \
		exit 1; \
	fi
	@MODEL_PATH="$(MODEL)"; \
	if [ "$${MODEL_PATH#/}" = "$$MODEL_PATH" ]; then \
		MODEL_PATH="$(shell pwd)/$$MODEL_PATH"; \
	fi; \
	if [ ! -f "$$MODEL_PATH" ]; then \
		echo "Error: Model file not found: $$MODEL_PATH"; \
		exit 1; \
	fi; \
	cd emblem5 && uv run --with-requirements ../requirements.txt python3 ./ai/verify_image.py "$$MODEL_PATH" "$(SBS_IMG)"

check-accuracy: FORCE
	@if [ -z "$(MODEL)" ]; then \
		echo "Error: MODEL is required. Usage: make check-accuracy MODEL=/path/to/model.pt [DATA_DIR=/path/to/data]"; \
		exit 1; \
	fi
	@MODEL_PATH="$(MODEL)"; \
	if [ "$${MODEL_PATH#/}" = "$$MODEL_PATH" ]; then \
		MODEL_PATH="$(shell pwd)/$$MODEL_PATH"; \
	fi; \
	if [ ! -f "$$MODEL_PATH" ]; then \
		echo "Error: Model file not found: $$MODEL_PATH"; \
		exit 1; \
	fi; \
	DATA_DIR="$(DATA_DIR)"; \
	if [ -z "$$DATA_DIR" ]; then \
		DATA_DIR="$(HOME)/emblem"; \
	fi; \
	cd emblem5 && uv run --with-requirements ../requirements.txt python3 ./ai/check_accuracy.py "$$MODEL_PATH" "$$DATA_DIR"

OPENCV_TAG := 4.9.0
opencv/src/LICENSE:
	rm -rf opencv/src opencv/contrib
	git clone --depth=1 https://gitlab.com/euphon/opencv_contrib opencv/contrib -b $(OPENCV_TAG)
	git clone --depth=1 https://gitlab.com/euphon/opencv opencv/src -b $(OPENCV_TAG)

opencv: opencv/src/LICENSE FORCE
	mkdir -p opencv/build/cpp opencv/install
	cd opencv/build/cpp && cmake \
	  -D CMAKE_BUILD_TYPE=RELEASE  \
	  -D CMAKE_INSTALL_PREFIX=$(PWD)/opencv/install  \
	  -D OPENCV_GENERATE_PKGCONFIG=ON  \
	  -D BUILD_EXAMPLES=OFF  \
	  -D INSTALL_PYTHON_EXAMPLES=OFF  \
	  -D INSTALL_C_EXAMPLES=OFF  \
	  -D BUILD_TESTS=OFF \
	  -D BUILD_PERF_TESTS=OFF \
	  -D OPENCV_EXTRA_MODULES_PATH=$(PWD)/opencv/contrib/modules \
	  -D BUILD_opencv_python2=OFF  \
	  -D BUILD_opencv_python3=OFF  \
	  -D WITH_PROTOBUF=ON \
	  -D BUILD_SHARED_LIBS=$(BUILD_SHARED_LIBS) \
	  -D WITH_GTK=OFF \
	  -D WITH_TIFF=OFF \
	  -D WITH_OPENGL=OFF \
	  -D WITH_JAVA=OFF \
	  -D WITH_PYTHON=OFF \
	  -D WITH_VA=OFF \
	  -D WITH_FREETYPE=OFF \
	  ../../src
	$(MAKE) -C opencv/build/cpp
	$(MAKE) -C opencv/build/cpp install

opencv.js: opencv/src/LICENSE FORCE
	mkdir -p opencv/build/wasm
	python3 opencv/src/platforms/js/build_js.py opencv/build/wasm \
	    --build_wasm \
	    --enable_exception \
	    --cmake_option="-DOPENCV_EXTRA_MODULES_PATH=$(PWD)/opencv/contrib/modules/" \
	    --cmake_option="-DWITH_PROTOBUF=off" \
	    --emscripten_dir=../emsdk/upstream/emscripten/ \
	    --disable_single_file

alg/qrtool:
	make -C alg qrtool

RELEASE_VERSION := $(shell git describe --tags --abbrev=0 | sed 's/^emblemscanner-//')

emblemscanner-release: build/emblemscanner-$(RELEASE_VERSION).zip

build/emblemscanner-$(RELEASE_VERSION).zip: FORCE
	- rm -rf $@
	git diff --exit-code
	if test -z "$(RELEASE_VERSION)"; then \
		echo "RELEASE_VERSION is empty"; \
		exit 1; \
	fi
	if [ $(shell git rev-parse emblemscanner-$(RELEASE_VERSION)) != $(shell git rev-parse HEAD) ]; then \
		echo "git head not tagged as $(RELEASE_VERSION)"; \
		exit 1; \
	fi
	cd scanner; zip -r ../build/emblemscanner-$(RELEASE_VERSION).zip pages/emblemscanner
	cd scanner/pages/emblemscanner && zip -g ../../../build/emblemscanner-$(RELEASE_VERSION).zip README.md
