
.PHONY: FORCE default
CV_DIR := $(shell pwd)/../opencv
CV_INSTALL_DIR := $(CV_DIR)/install
CV_WASM_DIR := $(CV_DIR)/build/wasm
CXX := ccache g++
CXXFLAGS := -O2 -std=c++17 -Wall -Werror -g -I$(CV_INSTALL_DIR)/include/opencv4


ifeq ($(shell uname), Darwin)
	RPATH_FLAG := -Wl,-rpath,'@executable_path/lib'
	STATIC :=
	IMAGE_VIEWER := open
else
	RPATH_FLAG := -Wl,-rpath,'$$ORIGIN/lib'
	STATIC := 1
	IMAGE_VIEWER := feh
endif

USE_PULSAR :=

ENABLE_GRPC :=

START_GROUP := -Wl,--start-group
END_GROUP := -Wl,--end-group

CV_PKG_CONFIG_PATH := $(shell pwd)/../opencv/install/lib/pkgconfig/

OPENCV_FLAGS := $(filter-out -lIconv::Iconv, \
	$(shell PKG_CONFIG_PATH=$(CV_PKG_CONFIG_PATH) pkg-config opencv4 --libs --cflags $(if $(STATIC), --static)) \
)

default: qrtool qrtool.wx.wasm.br qrtool.web.js

qrtool: CXXFLAGS += -DWECHAT_QRCODE_USE_MODEL=1

qrtool: qrtool.cpp libqr.cpp \
	$(if $(USE_PULSAR), mq_worker.cpp) \
	base64.cpp mq_worker.h base64.h \
	http.o \
	$(if $(ENABLE_GRPC), fileprocess.o fileprocess.pb.o fileprocess.grpc.pb.o) \
	Makefile
	$(CXX) -o $@ \
		$(if $(STATIC), -static) \
		$(filter %.cpp %.o, $^) \
		-DQRTOOL_MAIN=1 \
		$(if $(USE_PULSAR), -lpulsar) \
		$(CXXFLAGS) \
		$(RPATH_FLAG) \
		$(if $(STATIC), $(START_GROUP) -ljbig) \
		$(OPENCV_FLAGS) \
		$(if $(STATIC), $(END_GROUP)) \
		-Wno-error=unused-function \

qrtool.zip: qrtool
	rm -rf qrtool.zip-workdir
	mkdir -p qrtool.zip-workdir
	cp qrtool qrtool.zip-workdir/qrtool.$(shell git describe --always).x86_64
	cd qrtool.zip-workdir && zip qrtool.zip qrtool.$(shell git describe --always).x86_64 && mv qrtool.zip ..
	rm -rf qrtool.zip-workdir

angle: qrtool
	./qrtool angle dataset/camera/warp-small.jpg

verify: qrtool
	./qrtool verify ../dataset/similarity/19000-roi.jpg ../dataset/similarity/19000.jpg
	./qrtool verify ../dataset/similarity/19006-roi.jpg ../dataset/similarity/19006.jpg
	# ./qrtool verify ../dataset/local/scan-data/19687-roi.jpg ../dataset/local/scan-data/19687-frame.jpg

verify-neg: qrtool
	./qrtool verify ../dataset/similarity/19000-roi.jpg ../dataset/similarity/19002.jpg
	./qrtool verify ../dataset/similarity/19006-roi.jpg ../dataset/similarity/19002.jpg

verify-test: D := ../dataset/local/scan-data/
verify-test: qrtool FORCE
	for roi in $(shell ls $D | grep roi.jpg | sort -R | head -n 100); do \
		frame=$${roi/roi/frame}; \
		cmd="./qrtool verify $D/$$roi $D/$$frame"; \
		sim=$$($$cmd | grep similarity); \
		echo "<div class=case><img class=roi src=$$roi /> <img class=frame src=$$frame /><h1>$$sim</h1>"; \
		cat $D/$${roi/-roi.jpg/.txt}; \
		echo "</div>"; \
	done | tee $D/verify.html
	echo '<style> div.case { border: 1px solid green; padding: 1rem; margin: 1rem; } img.frame { width: 200px } img.roi { display: block }' >> $D/verify.html

rectify: qrtool
	./qrtool rectify dataset/camera/warp-small.jpg

roi: code=4295987837721
roi: qrtool
	./qrtool roi dataset/scan/$(code).jpg
	$(IMAGE_VIEWER) dataset/scan/$(code).jpg.roi.jpg

topleft: qrtool
	./qrtool topleft ../dataset/scandata/18986.jpg

roi_bench: qrtool
	begin=$$(date +%s); parallel -j10 ./qrtool roi_bench -- dataset/batches/*; end=$$(date +%s); nfiles=$$(find dataset/batches -type f | wc -l); echo total qps: $$((nfiles / (end - begin)))

imdecode: qrtool
	./qrtool imdecode dataset/camera/warp-small.jpg

angle-bench: qrtool
	time -f %e $(SHELL) -c '\
	for i in $(shell seq 100); do \
		$(library_path_prefix) \
		./qrtool angle dataset/camera/warp-small.jpg; \
	done'

neg: qrtool
	set -e; \
	for img in $(wildcard dataset/negative/*.jpg); do \
		if ./qrtool angle $$img; then echo "negative image check failed: $$img"; exit 1; fi; \
	done

detect: qrtool
	./qrtool detect dataset/camera/warp-small.jpg
detect2: qrtool
	./qrtool detect2 dataset/camera/warp-small.jpg

check: qrtool
	./qrtool check dataset/camera/warp-small.jpg

diagonal: qrtool
	./qrtool diagonal dataset/camera/warp-small.jpg

bench: qrtool
	./qrtool bench dataset/camera/warp-small.jpg

memory: qrtool
	valgrind ./qrtool bench dataset/camera/warp-small.jpg

fileprocess.o: fileprocess.grpc.pb.h

worker: qrtool
	./qrtool roi_worker roi

worker_nop: qrtool
	./qrtool roi_worker_nop roi

workers: qrtool
	parallel -j8 ./qrtool roi_worker -- roi roi roi roi roi roi roi roi

grpc: qrtool
	./qrtool grpc_server 0.0.0.0:32439

energy: qrtool FORCE
	$(library_path_prefix) \
	./qrtool energy dataset/roi/20231226/roi-1703563444.7468174.png

energy.html: qrtool FORCE
	ls dataset/roi/20231224/* | sort -R | head -n 100 | while read x; do \
		echo -n "<div>"; \
		$(library_path_prefix) \
		./qrtool energy $$x | tr -d '\n'; \
		echo -n " <img src=\"$$x\" />"; \
		echo "</div>"; \
	done | sort -rn -k 2 | tee $@
	google-chrome $@

hist.html: qrtool FORCE
	ls dataset/roi/20231224/* | grep -v hist | sort -R | head -n 100 | while read x; do \
		echo -n "<div>$$x"; \
		echo -n " <img src=\"$$x\" /><img height=60 width=60 src=\""; \
		$(library_path_prefix) \
		./qrtool $$x | tr -d '\n'; \
		echo "\"/></div>"; \
	done | sort -rn -k 2 | tee $@

dft.html: qrtool FORCE
	ls dataset/roi/20231224/* | grep -v dft | \
		while read x; do \
		echo -n "<div>$$x"; \
		echo -n " <img src=\"$$x\" /><img height=60 width=60 src=\""; \
		$(library_path_prefix) \
		./qrtool $$x | tr -d '\n'; \
		echo "\"/></div>"; \
	done | tee $@

dft-compare.html: qrtool FORCE
	(echo dataset/roi/20231224/roi-1703295645.003432.png; echo dataset/roi/20231224/roi-1703295645.365394.png) | \
		while read x; do \
		echo -n "<div>$$x"; \
		echo -n " <img src=\"$$x\" /><img height=60 width=60 src=\""; \
		$(library_path_prefix) \
		./qrtool $$x | tr -d '\n'; \
		echo "\"/></div>"; \
	done | sort -rn -k 2 | tee $@
	google-chrome $@

dft: qrtool FORCE
	$(library_path_prefix) \
	./qrtool dataset/camera/warp-small.jpg

qrtool.web.js: EMCC_FLAGS := \
		-O3

qrtool.wx.js: EMCC_FLAGS := \
		-O3 \
		--pre-js pre.wx.js \
		--post-js post.wx.js

SIMD128_OPTS := -msimd128
SIMD128_OPTS :=

qrtool.wx.js: pre.wx.js post.wx.js
qrtool.wx.js qrtool.web.js: qrtool_wasm.cpp libqr.cpp Makefile
	emcc \
		-o $@ -I$(CV_INSTALL_DIR)/include/opencv4 $(filter %.cpp, $^) \
		$(addprefix $(CV_WASM_DIR)/lib/, \
		libopencv_core.a \
		libopencv_dnn.a \
		libopencv_imgproc.a \
		libopencv_wechat_qrcode.a \
		) \
		$(addprefix $(CV_WASM_DIR)/3rdparty/lib/, \
		libzlib.a) \
		'-sEXPORTED_FUNCTIONS=["_qrtool_angle","_malloc","_free"]' \
		'-sEXPORTED_RUNTIME_METHODS=["ccall","cwrap","_wasm_call_ctors"]' \
		"-sMIN_CHROME_VERSION=73" \
		"-sMIN_SAFARI_VERSION=140100" \
		-sALLOW_MEMORY_GROWTH=1 \
		-sENVIRONMENT=web \
		$(SIMD128_OPTS) \
		-std=c++17 \
		-fexceptions \
		-lembind \
		-g1 \
		-sWASM=1 \
		$(EMCC_FLAGS)

qrtool.wx.wasm.br: qrtool.wx.js
	brotli -kf qrtool.wx.wasm

opencv: FORCE
	./opencv/euphon/build-cpp.sh

wasm: FORCE
	./opencv/euphon/build-wasm.sh

serve: qrtool FORCE
	$(library_path_prefix) \
	./server.py

deploy: FORCE
	set -e; \
	for kc in $(TARGET); do \
		echo $$kc; \
		kubectl --kubeconfig deploy/kubeconfig.$$kc set image deployment/alg alg=$(IMAGE); \
		kubectl --kubeconfig deploy/kubeconfig.$$kc rollout status deployment alg; \
	done

PROTO_DIR := ../../../cassia/estord/proto
fileprocess.grpc.pb.h fileprocess.grpc.pb.cc fileprocess.pb.h fileprocess.pb.cc: $(PROTO_DIR)/fileprocess.proto
	protoc -I $(PROTO_DIR) --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` $<
	protoc -I $(PROTO_DIR) --cpp_out=. $<

install-scanner: qrtool.wx.wasm.br
	@cp -v qrtool.wx.js qrtool.wx.wasm.br ../scanner/assets
	@cp -v qrtool.wx.js ../scanner/worker

install-web: qrtool.web.wasm
	@cp -v qrtool.web.js qrtool.web.wasm ../web/public/camera-4.0/js/

install: install-web install-scanner
