CC ?= gcc
CFLAGS ?= -O2 -std=c11 -Wall -Wextra -Werror
PYTHON ?= python3

ROOT := ..
TARGETS := test_imu_calibration test_gps_nav_epoch \
	test_gps_nav_epoch_coalescing test_gps_time_anchor \
	test_plic_warm_reset test_gps_acq_manager \
	test_gps_ephemeris_cache test_gps_receiver_hardware_sim
TARGETS += test_gps_measurement_freshness
TARGETS += test_gps_nav_phase
TARGETS += test_gps_tracking_measurement
TARGETS += test_gps_satellite_velocity
TARGETS += test_gps_pps_time_filter
TARGETS += test_gps_pps_quality
TARGETS += test_gps_pps_adaptive_loop
TARGETS += test_gps_visibility
TARGETS += test_gps_almanac
TARGETS += test_gps_flash_journal
TARGETS += test_gps_assistance_data
TARGETS += test_gps_assistance_store

.PHONY: all run python-models sanitize clean

all: $(TARGETS)

test_imu_calibration: test_imu_calibration.c $(ROOT)/src/imu/imu_calibration.c
	$(CC) $(CFLAGS) -I$(ROOT)/header $^ -lm -o $@

test_gps_nav_epoch: test_gps_nav_epoch.c $(ROOT)/src/gps/gps_nav_epoch.c
	$(CC) $(CFLAGS) -I$(ROOT)/header $^ -lm -o $@

test_gps_nav_epoch_coalescing: test_gps_nav_epoch_coalescing.c $(ROOT)/src/gps/gps_nav_epoch.c
	$(CC) $(CFLAGS) -I$(ROOT)/header $^ -lm -o $@

test_gps_time_anchor: test_gps_time_anchor.c $(ROOT)/src/gps/gps_time_anchor.c
	$(CC) $(CFLAGS) -I$(ROOT)/header $^ -lm -o $@

test_gps_measurement_freshness: test_gps_measurement_freshness.c \
		$(ROOT)/src/gps/gps_measurement_freshness.c
	$(CC) $(CFLAGS) -I$(ROOT)/header $^ -o $@

test_gps_nav_phase: test_gps_nav_phase.c
	$(CC) $(CFLAGS) -Wno-comment -Ifake_bsp -I$(ROOT)/header $^ -o $@

test_plic_warm_reset: test_plic_warm_reset.c $(ROOT)/../bsp/drivers/plic.c
	$(CC) $(CFLAGS) -Ifake_bsp -I$(ROOT)/../bsp/include $^ -o $@

test_gps_acq_manager: test_gps_acq_manager.c $(ROOT)/src/gps/gps_acq_manager.c
	$(CC) $(CFLAGS) -I$(ROOT)/header $^ -o $@

test_gps_visibility: test_gps_visibility.c $(ROOT)/src/gps/gps_visibility.c
	$(CC) $(CFLAGS) -I$(ROOT)/header $^ -lm -o $@

test_gps_ephemeris_cache: test_gps_ephemeris_cache.c $(ROOT)/src/gps/gps_ephemeris_cache.c
	$(CC) $(CFLAGS) -Wno-comment -Ifake_bsp -I$(ROOT)/header $^ -o $@

test_gps_almanac: test_gps_almanac.c \
		$(ROOT)/src/gps/gps_almanac.c \
		$(ROOT)/src/gps/NavEquations.c \
		$(ROOT)/src/gps/matrixLib.c
	$(CC) $(CFLAGS) -Wno-comment -Wno-unused-parameter \
		-Wno-unused-variable -Wno-sign-compare \
		-Ifake_bsp -I$(ROOT)/header $^ -lm -o $@

test_gps_flash_journal: test_gps_flash_journal.c \
		$(ROOT)/src/gps/gps_flash_journal.c
	$(CC) $(CFLAGS) -I$(ROOT)/header $^ -o $@

test_gps_assistance_data: test_gps_assistance_data.c \
		$(ROOT)/src/gps/gps_assistance_data.c \
		$(ROOT)/src/gps/gps_ephemeris_cache.c \
		$(ROOT)/src/gps/gps_almanac.c \
		$(ROOT)/src/gps/gps_time_anchor.c
	$(CC) $(CFLAGS) -Wno-comment -Ifake_bsp -I$(ROOT)/header $^ -lm -o $@

test_gps_assistance_store: test_gps_assistance_store.c \
		$(ROOT)/src/gps/gps_assistance_store.c \
		$(ROOT)/src/gps/gps_assistance_data.c \
		$(ROOT)/src/gps/gps_flash_journal.c \
		$(ROOT)/src/gps/gps_ephemeris_cache.c \
		$(ROOT)/src/gps/gps_almanac.c \
		$(ROOT)/src/gps/gps_time_anchor.c
	$(CC) $(CFLAGS) -Wno-comment -Ifake_bsp -I$(ROOT)/header $^ -lm -o $@

test_gps_receiver_hardware_sim: test_gps_receiver_hardware_sim.c \
		$(ROOT)/src/gps/gps_acq_manager.c \
		$(ROOT)/src/gps/gps_almanac.c \
		$(ROOT)/src/gps/gps_ephemeris_cache.c
	$(CC) $(CFLAGS) -Wno-comment -Ifake_bsp -I$(ROOT)/header $^ -lm -o $@

test_gps_tracking_measurement: test_gps_tracking_measurement.c \
		$(ROOT)/src/gps/gps_tracking_measurement.c
	$(CC) $(CFLAGS) -Wno-comment -Ifake_bsp -I$(ROOT)/header $^ -lm -o $@

test_gps_satellite_velocity: test_gps_satellite_velocity.c \
		$(ROOT)/src/gps/NavEquations.c \
		$(ROOT)/src/gps/matrixLib.c
	$(CC) $(CFLAGS) -Wno-comment -Wno-unused-parameter \
		-Wno-unused-variable -Wno-sign-compare \
		-Ifake_bsp -I$(ROOT)/header $^ -lm -o $@

test_gps_pps_time_filter: test_gps_pps_time_filter.c \
		$(ROOT)/src/gps/gps_pps_time_filter.c
	$(CC) $(CFLAGS) -I$(ROOT)/header $^ -lm -o $@

test_gps_pps_quality: test_gps_pps_quality.c \
		$(ROOT)/src/gps/gps_pps_quality.c
	$(CC) $(CFLAGS) -I$(ROOT)/header $^ -lm -o $@

test_gps_pps_adaptive_loop: test_gps_pps_adaptive_loop.c \
		$(ROOT)/src/gps/gps_pps_time_filter.c \
		$(ROOT)/src/gps/gps_pps_quality.c
	$(CC) $(CFLAGS) -I$(ROOT)/header $^ -lm -o $@

run: $(TARGETS)
	./test_imu_calibration
	./test_gps_nav_epoch
	./test_gps_nav_epoch_coalescing
	./test_gps_time_anchor
	./test_gps_measurement_freshness
	./test_gps_nav_phase
	./test_plic_warm_reset
	./test_gps_acq_manager
	./test_gps_ephemeris_cache
	./test_gps_almanac
	./test_gps_flash_journal
	./test_gps_assistance_data
	./test_gps_assistance_store
	./test_gps_receiver_hardware_sim
	./test_gps_tracking_measurement
	./test_gps_satellite_velocity
	./test_gps_pps_time_filter
	./test_gps_pps_quality
	./test_gps_pps_adaptive_loop
	./test_gps_visibility
	$(PYTHON) test_acq_search_model.py

python-models:
	$(PYTHON) test_acq_search_model.py

sanitize:
	$(CC) -O1 -g -std=c11 -Wall -Wextra -Werror \
		-fsanitize=address,undefined -fno-omit-frame-pointer \
		-I$(ROOT)/header test_gps_nav_epoch.c \
		$(ROOT)/src/gps/gps_nav_epoch.c -lm \
		-o test_gps_nav_epoch_san
	ASAN_OPTIONS=detect_leaks=1:halt_on_error=1 \
		UBSAN_OPTIONS=halt_on_error=1 ./test_gps_nav_epoch_san
	$(CC) -O1 -g -std=c11 -Wall -Wextra -Werror \
		-fsanitize=address,undefined -fno-omit-frame-pointer \
		-I$(ROOT)/header test_gps_nav_epoch_coalescing.c \
		$(ROOT)/src/gps/gps_nav_epoch.c -lm \
		-o test_gps_nav_epoch_coalescing_san
	ASAN_OPTIONS=detect_leaks=1:halt_on_error=1 \
		UBSAN_OPTIONS=halt_on_error=1 ./test_gps_nav_epoch_coalescing_san
	$(CC) -O1 -g -std=c11 -Wall -Wextra -Werror \
		-fsanitize=address,undefined -fno-omit-frame-pointer \
		-I$(ROOT)/header test_gps_time_anchor.c \
		$(ROOT)/src/gps/gps_time_anchor.c -lm \
		-o test_gps_time_anchor_san
	ASAN_OPTIONS=detect_leaks=1:halt_on_error=1 \
		UBSAN_OPTIONS=halt_on_error=1 ./test_gps_time_anchor_san
	$(CC) -O1 -g -std=c11 -Wall -Wextra -Werror \
		-fsanitize=address,undefined -fno-omit-frame-pointer \
		-I$(ROOT)/header test_gps_measurement_freshness.c \
		$(ROOT)/src/gps/gps_measurement_freshness.c \
		-o test_gps_measurement_freshness_san
	ASAN_OPTIONS=detect_leaks=1:halt_on_error=1 \
		UBSAN_OPTIONS=halt_on_error=1 ./test_gps_measurement_freshness_san
	$(CC) -O1 -g -std=c11 -Wall -Wextra -Werror \
		-fsanitize=address,undefined -fno-omit-frame-pointer \
		-Wno-comment -Ifake_bsp -I$(ROOT)/header \
		test_gps_nav_phase.c -o test_gps_nav_phase_san
	ASAN_OPTIONS=detect_leaks=1:halt_on_error=1 \
		UBSAN_OPTIONS=halt_on_error=1 ./test_gps_nav_phase_san
	$(CC) -O1 -g -std=c11 -Wall -Wextra -Werror \
		-fsanitize=address,undefined -fno-omit-frame-pointer \
		-I$(ROOT)/header test_gps_acq_manager.c \
		$(ROOT)/src/gps/gps_acq_manager.c \
		-o test_gps_acq_manager_san
	ASAN_OPTIONS=detect_leaks=1:halt_on_error=1 \
		UBSAN_OPTIONS=halt_on_error=1 ./test_gps_acq_manager_san
	$(CC) -O1 -g -std=c11 -Wall -Wextra -Werror \
		-fsanitize=address,undefined -fno-omit-frame-pointer \
		-Wno-comment -Ifake_bsp -I$(ROOT)/header \
		test_gps_ephemeris_cache.c \
		$(ROOT)/src/gps/gps_ephemeris_cache.c \
		-o test_gps_ephemeris_cache_san
	ASAN_OPTIONS=detect_leaks=1:halt_on_error=1 \
		UBSAN_OPTIONS=halt_on_error=1 ./test_gps_ephemeris_cache_san
	$(CC) -O1 -g -std=c11 -Wall -Wextra -Werror \
		-fsanitize=address,undefined -fno-omit-frame-pointer \
		-Wno-comment -Wno-unused-parameter -Wno-unused-variable \
		-Wno-sign-compare -Ifake_bsp -I$(ROOT)/header \
		test_gps_almanac.c \
		$(ROOT)/src/gps/gps_almanac.c \
		$(ROOT)/src/gps/NavEquations.c \
		$(ROOT)/src/gps/matrixLib.c -lm \
		-o test_gps_almanac_san
	ASAN_OPTIONS=detect_leaks=1:halt_on_error=1 \
		UBSAN_OPTIONS=halt_on_error=1 ./test_gps_almanac_san
	$(CC) -O1 -g -std=c11 -Wall -Wextra -Werror \
		-fsanitize=address,undefined -fno-omit-frame-pointer \
		-I$(ROOT)/header test_gps_flash_journal.c \
		$(ROOT)/src/gps/gps_flash_journal.c \
		-o test_gps_flash_journal_san
	ASAN_OPTIONS=detect_leaks=1:halt_on_error=1 \
		UBSAN_OPTIONS=halt_on_error=1 ./test_gps_flash_journal_san
	$(CC) -O1 -g -std=c11 -Wall -Wextra -Werror \
		-fsanitize=address,undefined -fno-omit-frame-pointer \
		-Wno-comment -Ifake_bsp -I$(ROOT)/header \
		test_gps_assistance_data.c \
		$(ROOT)/src/gps/gps_assistance_data.c \
		$(ROOT)/src/gps/gps_ephemeris_cache.c \
		$(ROOT)/src/gps/gps_almanac.c \
		$(ROOT)/src/gps/gps_time_anchor.c -lm \
		-o test_gps_assistance_data_san
	ASAN_OPTIONS=detect_leaks=1:halt_on_error=1 \
		UBSAN_OPTIONS=halt_on_error=1 ./test_gps_assistance_data_san
	$(CC) -O1 -g -std=c11 -Wall -Wextra -Werror \
		-fsanitize=address,undefined -fno-omit-frame-pointer \
		-Wno-comment -Ifake_bsp -I$(ROOT)/header \
		test_gps_assistance_store.c \
		$(ROOT)/src/gps/gps_assistance_store.c \
		$(ROOT)/src/gps/gps_assistance_data.c \
		$(ROOT)/src/gps/gps_flash_journal.c \
		$(ROOT)/src/gps/gps_ephemeris_cache.c \
		$(ROOT)/src/gps/gps_almanac.c \
		$(ROOT)/src/gps/gps_time_anchor.c -lm \
		-o test_gps_assistance_store_san
	ASAN_OPTIONS=detect_leaks=1:halt_on_error=1 \
		UBSAN_OPTIONS=halt_on_error=1 ./test_gps_assistance_store_san
	$(CC) -O1 -g -std=c11 -Wall -Wextra -Werror \
		-fsanitize=address,undefined -fno-omit-frame-pointer \
		-Wno-comment -Ifake_bsp -I$(ROOT)/header \
		test_gps_receiver_hardware_sim.c \
		$(ROOT)/src/gps/gps_acq_manager.c \
		$(ROOT)/src/gps/gps_almanac.c \
		$(ROOT)/src/gps/gps_ephemeris_cache.c \
		-lm -o test_gps_receiver_hardware_sim_san
	ASAN_OPTIONS=detect_leaks=1:halt_on_error=1 \
		UBSAN_OPTIONS=halt_on_error=1 \
		./test_gps_receiver_hardware_sim_san
	$(CC) -O1 -g -std=c11 -Wall -Wextra -Werror \
		-fsanitize=address,undefined -fno-omit-frame-pointer \
		-Wno-comment -Ifake_bsp -I$(ROOT)/header \
		test_gps_tracking_measurement.c \
		$(ROOT)/src/gps/gps_tracking_measurement.c -lm \
		-o test_gps_tracking_measurement_san
	ASAN_OPTIONS=detect_leaks=1:halt_on_error=1 \
		UBSAN_OPTIONS=halt_on_error=1 \
		./test_gps_tracking_measurement_san
	$(CC) -O1 -g -std=c11 -Wall -Wextra -Werror \
		-fsanitize=address,undefined -fno-omit-frame-pointer \
		-Wno-comment -Wno-unused-parameter -Wno-unused-variable \
		-Wno-sign-compare -Ifake_bsp -I$(ROOT)/header \
		test_gps_satellite_velocity.c \
		$(ROOT)/src/gps/NavEquations.c \
		$(ROOT)/src/gps/matrixLib.c -lm \
		-o test_gps_satellite_velocity_san
	ASAN_OPTIONS=detect_leaks=1:halt_on_error=1 \
		UBSAN_OPTIONS=halt_on_error=1 \
		./test_gps_satellite_velocity_san
	$(CC) -O1 -g -std=c11 -Wall -Wextra -Werror \
		-fsanitize=address,undefined -fno-omit-frame-pointer \
		-I$(ROOT)/header test_gps_pps_time_filter.c \
		$(ROOT)/src/gps/gps_pps_time_filter.c -lm \
		-o test_gps_pps_time_filter_san
	ASAN_OPTIONS=detect_leaks=1:halt_on_error=1 \
		UBSAN_OPTIONS=halt_on_error=1 ./test_gps_pps_time_filter_san
	$(CC) -O1 -g -std=c11 -Wall -Wextra -Werror \
		-fsanitize=address,undefined -fno-omit-frame-pointer \
		-I$(ROOT)/header test_gps_pps_quality.c \
		$(ROOT)/src/gps/gps_pps_quality.c -lm \
		-o test_gps_pps_quality_san
	ASAN_OPTIONS=detect_leaks=1:halt_on_error=1 \
		UBSAN_OPTIONS=halt_on_error=1 ./test_gps_pps_quality_san
	$(CC) -O1 -g -std=c11 -Wall -Wextra -Werror \
		-fsanitize=address,undefined -fno-omit-frame-pointer \
		-I$(ROOT)/header test_gps_pps_adaptive_loop.c \
		$(ROOT)/src/gps/gps_pps_time_filter.c \
		$(ROOT)/src/gps/gps_pps_quality.c -lm \
		-o test_gps_pps_adaptive_loop_san
	ASAN_OPTIONS=detect_leaks=1:halt_on_error=1 \
		UBSAN_OPTIONS=halt_on_error=1 ./test_gps_pps_adaptive_loop_san
	$(CC) -O1 -g -std=c11 -Wall -Wextra -Werror \
		-fsanitize=address,undefined -fno-omit-frame-pointer \
		-I$(ROOT)/header test_gps_visibility.c \
		$(ROOT)/src/gps/gps_visibility.c -lm \
		-o test_gps_visibility_san
	ASAN_OPTIONS=detect_leaks=1:halt_on_error=1 \
		UBSAN_OPTIONS=halt_on_error=1 ./test_gps_visibility_san

clean:
	rm -f $(TARGETS) test_gps_nav_epoch_coalescing_repro \
		test_gps_nav_epoch_san test_gps_nav_epoch_coalescing_san \
		test_gps_time_anchor_san \
		test_gps_measurement_freshness_san test_gps_nav_phase_san \
		test_gps_acq_manager_san test_gps_ephemeris_cache_san \
		test_gps_almanac_san \
		test_gps_flash_journal_san \
		test_gps_assistance_data_san \
		test_gps_assistance_store_san \
		test_gps_receiver_hardware_sim_san \
		test_gps_tracking_measurement_san \
		test_gps_satellite_velocity_san \
		test_gps_pps_time_filter_san test_gps_pps_quality_san \
		test_gps_pps_adaptive_loop_san test_gps_visibility_san
