PYTHON ?= uv run --extra dev python
UV ?= uv
PYTEST ?= $(PYTHON) -m pytest
COVERAGE ?= $(PYTHON) -m coverage
SPEECH_TEST := tests/brain/test_speech.py
VISION_TEST := tests/brain/test_vision.py
BASE_TEST := tests/base
TYPES_TEST := tests/types
ROBOT_TEST := tests/robots
SPEECH_COVERAGE_FILE := /tmp/boosteros_test_speech.coverage
VISION_COVERAGE_FILE := /tmp/boosteros_test_vision.coverage
BASE_COVERAGE_FILE := /tmp/boosteros_test_base.coverage
TYPES_COVERAGE_FILE := /tmp/boosteros_test_types.coverage
ROBOT_COVERAGE_FILE := /tmp/boosteros_test_robots.coverage
ALL_OFFLINE_PROFILES := humble-aarch64 humble-x86_64 kilted-aarch64 kilted-x86_64
OFFLINE_PROFILE ?= auto
OFFLINE_INPUT_ROOT ?= build/offline-inputs/$(OFFLINE_PROFILE)
OFFLINE_OUTPUT_DIR ?= dist/offline
OFFLINE_CONSTRAINTS_FILE ?= scripts/offline/constraints/core.txt

OFFLINE_APT_REPO ?=
OFFLINE_INDEX_URL ?= https://mirrors.aliyun.com/pypi/simple/
OFFLINE_EXTRA_INDEX_URL ?= https://test.pypi.org/simple/
OFFLINE_LOCAL_WHEEL_DIR ?=
OFFLINE_BOOSTEROS_WHEEL ?=
OFFLINE_CONSTRAINTS ?=
OFFLINE_FORCE_BUILD_WHEEL ?= 0
OFFLINE_PIP_BIN ?=
OFFLINE_APT_UBUNTU_MIRROR ?=
OFFLINE_APT_ROS_MIRROR ?=

OFFLINE_APT_REPO_ARG :=
OFFLINE_PREPARE_APT_TARGET := prepare-offline-apt-repo
ifneq ($(strip $(OFFLINE_APT_REPO)),)
OFFLINE_APT_REPO_ARG := --apt-repo $(OFFLINE_APT_REPO)
OFFLINE_PREPARE_APT_TARGET :=
endif

OFFLINE_BOOSTEROS_WHEEL_ARG :=
ifneq ($(strip $(OFFLINE_BOOSTEROS_WHEEL)),)
OFFLINE_BOOSTEROS_WHEEL_ARG := --boosteros-wheel $(OFFLINE_BOOSTEROS_WHEEL)
endif

OFFLINE_CONSTRAINTS_ARG :=
ifneq ($(strip $(OFFLINE_CONSTRAINTS)),)
OFFLINE_CONSTRAINTS_ARG := --constraints $(OFFLINE_CONSTRAINTS)
endif

OFFLINE_FORCE_BUILD_WHEEL_ARG :=
ifneq ($(filter 1 yes true,$(strip $(OFFLINE_FORCE_BUILD_WHEEL))),)
OFFLINE_FORCE_BUILD_WHEEL_ARG := --force-build-wheel
endif

OFFLINE_LOCAL_WHEEL_DIR_ARG :=
ifneq ($(strip $(OFFLINE_LOCAL_WHEEL_DIR)),)
OFFLINE_LOCAL_WHEEL_DIR_ARG := --local-wheel-dir "$(OFFLINE_LOCAL_WHEEL_DIR)"
endif

OFFLINE_PIP_ENV :=
ifneq ($(strip $(OFFLINE_PIP_BIN)),)
OFFLINE_PIP_ENV := PIP_BIN="$(OFFLINE_PIP_BIN)"
endif

OFFLINE_APT_UBUNTU_MIRROR_ARG :=
ifneq ($(strip $(OFFLINE_APT_UBUNTU_MIRROR)),)
OFFLINE_APT_UBUNTU_MIRROR_ARG := --ubuntu-mirror "$(OFFLINE_APT_UBUNTU_MIRROR)"
endif

OFFLINE_APT_ROS_MIRROR_ARG :=
ifneq ($(strip $(OFFLINE_APT_ROS_MIRROR)),)
OFFLINE_APT_ROS_MIRROR_ARG := --ros-mirror "$(OFFLINE_APT_ROS_MIRROR)"
endif

.PHONY: build-debug build-clean generate-offline-constraints prepare-offline-wheelhouse prepare-offline-apt-repo build-offline-run build-offline-package offline-package docker-install install-to-docker ut ut-speech ut-vision ut-base ut-types ut-robots ut-cov ut-speech-cov ut-vision-cov ut-base-cov ut-types-cov ut-robots-cov

default: build-debug

build-debug:
	./scripts/build_debug.sh

build-clean:
	rm -rf dist

generate-offline-constraints:
	$(UV) export --locked --offline --no-cache --no-dev --no-emit-project --no-emit-package booster-robotics-sdk-python --no-hashes --no-annotate --output-file "$(OFFLINE_CONSTRAINTS_FILE)"

prepare-offline-wheelhouse:
	$(OFFLINE_PIP_ENV) ./scripts/offline/prepare_wheelhouse.sh --profile "$(OFFLINE_PROFILE)" --output-root "$(OFFLINE_INPUT_ROOT)" --index-url "$(OFFLINE_INDEX_URL)" --extra-index-url "$(OFFLINE_EXTRA_INDEX_URL)" $(OFFLINE_LOCAL_WHEEL_DIR_ARG) $(OFFLINE_BOOSTEROS_WHEEL_ARG) $(OFFLINE_CONSTRAINTS_ARG) $(OFFLINE_FORCE_BUILD_WHEEL_ARG)

prepare-offline-apt-repo:
	./scripts/offline/prepare_apt_repo.sh --profile "$(OFFLINE_PROFILE)" --output-root "$(OFFLINE_INPUT_ROOT)" $(OFFLINE_APT_UBUNTU_MIRROR_ARG) $(OFFLINE_APT_ROS_MIRROR_ARG)

build-offline-single-run:
	./scripts/offline/build_run.sh --profile "$(OFFLINE_PROFILE)" --input-root "$(OFFLINE_INPUT_ROOT)" --output-dir "$(OFFLINE_OUTPUT_DIR)" $(OFFLINE_APT_REPO_ARG)

build-offline-run:
ifeq ($(OFFLINE_PROFILE),auto)
	@for p in $(ALL_OFFLINE_PROFILES); do \
		echo "=================================================="; \
		echo "[INFO] Building offline run for profile: $$p"; \
		echo "=================================================="; \
		$(MAKE) build-offline-single-run OFFLINE_PROFILE="$$p" OFFLINE_INPUT_ROOT="build/offline-inputs/$$p" || exit 1; \
	done
else
	$(MAKE) build-offline-single-run
endif

build-offline-package offline-package:
ifeq ($(OFFLINE_PROFILE),auto)
	@for p in $(ALL_OFFLINE_PROFILES); do \
		echo "=================================================="; \
		echo "[INFO] Building offline package for profile: $$p"; \
		echo "=================================================="; \
		$(MAKE) build-offline-package OFFLINE_PROFILE="$$p" OFFLINE_INPUT_ROOT="build/offline-inputs/$$p" || exit 1; \
	done
else
	$(MAKE) prepare-offline-wheelhouse $(OFFLINE_PREPARE_APT_TARGET)
	$(MAKE) build-offline-single-run
endif

docker-install install-to-docker:
	CONTAINER="$(CONTAINER)" REMOTE_WHEEL_DIR="$(REMOTE_WHEEL_DIR)" REMOTE_WORKSPACE="$(REMOTE_WORKSPACE)" PYTHON_BIN="$(PYTHON_BIN)" ./scripts/install_to_docker.sh

ut: ut-speech ut-vision ut-base ut-types ut-robots

ut-speech:
	$(PYTEST) $(SPEECH_TEST) -q

ut-vision:
	$(PYTEST) $(VISION_TEST) -q

ut-base:
	$(PYTEST) $(BASE_TEST) -q

ut-types:
	$(PYTEST) $(TYPES_TEST) -q

ut-robots:
	$(PYTEST) $(ROBOT_TEST) -q

ut-cov: ut-speech-cov ut-vision-cov ut-base-cov ut-types-cov ut-robots-cov

ut-speech-cov:
	COVERAGE_FILE=$(SPEECH_COVERAGE_FILE) \
		$(COVERAGE) run --source=src/boosteros/brain/speech \
		-m pytest $(SPEECH_TEST) -q
	COVERAGE_FILE=$(SPEECH_COVERAGE_FILE) $(COVERAGE) report -m

ut-vision-cov:
	COVERAGE_FILE=$(VISION_COVERAGE_FILE) \
		$(COVERAGE) run --source=src/boosteros/brain/vision \
		-m pytest $(VISION_TEST) -q
	COVERAGE_FILE=$(VISION_COVERAGE_FILE) $(COVERAGE) report -m

ut-base-cov:
	COVERAGE_FILE=$(BASE_COVERAGE_FILE) \
		$(COVERAGE) run --source=src/boosteros/base \
		-m pytest $(BASE_TEST) -q
	COVERAGE_FILE=$(BASE_COVERAGE_FILE) $(COVERAGE) report -m

ut-types-cov:
	COVERAGE_FILE=$(TYPES_COVERAGE_FILE) \
		$(COVERAGE) run --source=src/boosteros/types \
		-m pytest $(TYPES_TEST) -q
	COVERAGE_FILE=$(TYPES_COVERAGE_FILE) $(COVERAGE) report -m

ut-robots-cov:
	COVERAGE_FILE=$(ROBOT_COVERAGE_FILE) \
		$(COVERAGE) run --source=src/boosteros/robots \
		-m pytest $(ROBOT_TEST) -q
	COVERAGE_FILE=$(ROBOT_COVERAGE_FILE) $(COVERAGE) report -m
