# These have been configured to only really run short tasks. Longer form tasks
# are usually completed in github actions.
# Paths are relative to the Makefile location.

SHELL := /bin/bash

NAME := CARP-S
PACKAGE_NAME := carps
VERSION := 1.1.0

DIST := dist

.PHONY: help install-dev clean-build check build docs publish test

# TODO update help in Makefile
help:
	@echo "Makefile ${NAME}"
	@echo "* install-dev      to install all dev requirements and install pre-commit"
	@echo "* clean-build      to clean any build files"
	@echo "* check            to run the pre-commit check"
	@echo "* build            to build a dist"
	@echo "* docs             to generate and view the html files, checks links"
	@echo "* publish          to help publish the current branch to pypi"
	@echo "* test             to run the tests"

PYTHON ?= python

ifndef PIP
ifeq ($(shell command -v uv 2>/dev/null),)
    PIP := pip
else
    PIP := uv pip
endif
endif

test:
	$(PYTHON) -m pytest tests/test_configs.py tests/test_optimizers.py tests/test_tasks.py -n 8 --lf -x

docs:
	$(PYTHON) -m webbrowser -t "http://127.0.0.1:8000/"
	$(PYTHON) -m properdocs serve --clean

check:
	pre-commit run --all-files

install-dev:
	$(PIP) install -e "../..[dev]"
	pre-commit install

clean-build:
	rm -rf ${DIST}

# Build a distribution in ./dist
build:
	$(PYTHON) -m $(PIP) install build
	$(PYTHON) -m build --sdist

# Publish to testpypi
# Will echo the commands to actually publish to be run to publish to actual PyPi
# This is done to prevent accidental publishing but provide the same conveniences
publish: clean-build build
	read -p "Did you update the version number in Makefile, pyproject.toml, and CITATION.cff?"

	$(PIP) install twine
	$(PYTHON) -m twine upload --repository testpypi ${DIST}/*
	@echo
	@echo "Test with the following:"
	@echo "* Create a new virtual environment to install the uploaded distribution into"
	@echo "* Run the following:"
	@echo "--- pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ ${PACKAGE_NAME}==${VERSION}"
	@echo
	@echo "* Run this to make sure it can import correctly, plus whatever else you'd like to test:"
	@echo "--- python -c 'import ${PACKAGE_NAME}'"
	@echo
	@echo "Once you have decided it works, publish to actual pypi with"
	@echo "--- python -m twine upload dist/*"


OS := $(shell uname)

uvenv:
	pip install uv
	export PATH="$HOME/.local/bin:$PATH"
	uv venv --python=3.13 .venv
	. .venv/bin/activate && \
		python -m ensurepip --upgrade && \
		python -m pip install uv --upgrade  && \
		uv pip install setuptools wheel  && \

optimizer_smac:
	$(PIP) install swig
	$(PIP) install -r ../container/recipes/optimizers/SMAC3/SMAC3_requirements.txt

optimizer_optuna:
	$(PIP) install -r ../container/recipes/optimizers/Optuna/Optuna_requirements.txt

optimizer_dehb:
	$(PIP) install -r ../container/recipes/optimizers/DEHB/DEHB_requirements.txt
	$(PIP) install "numpy<2.5.0"

optimizer_skopt:
	$(PIP) install -r ../container/recipes/optimizers/Scikit_Optimize/Scikit_Optimize_requirements.txt

optimizer_synetune:
# 	$(PIP) install -r ../container/recipes/optimizers/SyneTune/SyneTune_requirements.txt
	git clone https://github.com/awslabs/syne-tune.git lib/syne-tune || true
	$(PIP) install -e 'lib/syne-tune[extra]'
	$(PIP) install statsmodels
	$(PIP) install "numpy<2.5.0"
	$(PIP) install xgboost --upgrade

optimizer_ax:
	$(PIP) install -r ../container/recipes/optimizers/Ax/Ax_requirements.txt
	$(PIP) install "numpy<2.5.0"

optimizer_hebo:
	# . ../container/recipes/optimizers/HEBO/HEBO_install.sh
	$(PIP) install -r ../container/recipes/optimizers/HEBO/HEBO_requirements.txt
	$(PIP) install "numpy<2.5.0"

optimizer_nevergrad:
	$(PIP) install -r ../container/recipes/optimizers/Nevergrad/Nevergrad_requirements.txt
	$(PIP) install "numpy<2.5.0"
	$(PIP) install cma --upgrade

benchmark_bbob:
	# Install BBOB
	$(PIP) install ioh
	$(PIP) install "numpy<2.5.0"

benchmark_yahpo:
# Needs 2GB of space for the surrogate models of YAHPO
	# Install yahpo
	. ../container/recipes/benchmarks/YAHPO/install_yahpo.sh
	$(PIP) install ConfigSpace --upgrade
	$(PIP) install "numpy<2.5.0"

benchmark_pymoo:
	# Install pymoo
	$(PIP) install -r ../container/recipes/benchmarks/Pymoo/Pymoo_requirements.txt

benchmark_mfpbench:
	# Install mfpbench
	$(PIP) install mf-prior-bench
	$(PIP) install xgboost --upgrade
	$(PIP) install ConfigSpace --upgrade
	. ../container/recipes/benchmarks/MFPBench/download_data.sh

benchmark_hpobench:
	# Install hpobench
	. ../container/recipes/benchmarks/HPOBench/install_HPOBench.sh

benchmark_hpob:
	# Install hpob
	$(PIP) install -r ../container/recipes/benchmarks/HPOB/HPOB_requirements.txt
	. ../container/recipes/benchmarks/HPOB/download_data.sh

benchmark_nasengb:
	@if [ ! -d "lib/naseng_benchmark" ]; then \
		git clone https://github.com/luh-ai/naseng_benchmark.git lib/naseng_benchmark; \
	else \
		echo "lib/naseng_benchmark already exists, skipping clone and just pull" && git pull; \
	fi
	$(PIP) install -e lib/naseng_benchmark
	$(PIP) install py-pde torchvision swig gymnasium[box2d] --upgrade

benchmark_papenbench:
	$(PIP) install git+https://github.com/lpapenme/BencherScaffold
	. ../container/recipes/benchmarks/PapenBench/build_container.sh
	@if [ ! -d "lib/bencher" ]; then \
		git clone https://github.com/lpapenme/bencher.git lib/bencher; \
	else \
		echo "lib/bencher already exists, skipping clone and just pull" && git pull; \
	fi
	$(PIP) install lib/bencher/BencherServer
	$(PIP) install "numpy<2.5.0"

benchmarks:
	$(MAKE) benchmark_bbob
	$(MAKE) benchmark_yahpo
	$(MAKE) benchmark_pymoo
	$(MAKE) benchmark_mfpbench
	$(MAKE) benchmark_hpobench
# 	$(MAKE) benchmark_hpob
	$(MAKE) benchmark_nasengb
	$(MAKE) benchmark_papenbench

optimizers:
	$(MAKE) optimizer_smac
	$(MAKE) optimizer_optuna
	$(MAKE) optimizer_dehb
	$(MAKE) optimizer_skopt
	$(MAKE) optimizer_synetune
	$(MAKE) optimizer_ax
	$(MAKE) optimizer_nevergrad
	# $(MAKE) optimizer_hebo

all:
	$(MAKE) benchmarks
	$(MAKE) optimizers

default:
	echo "Installed carps. If you want to install the benchmarks and optimizers, pass 'all' or e.g."
	echo "'benchmark_bbob optimizer_smac'"
