# Semana 12: funciones como valores. Se usa dentro del entorno del curso.
#
#   make           compila los programas de la clase en build/
#   make lab       compila el laboratorio en build/lab/
#   make test      corre las pruebas de los ejemplos y de los apuntes
#   make test-lab  prueba su laboratorio; falla hasta que lo terminen
#   make clean     borra lo generado
#
# Los programas de errors/ tienen errores a propósito. No se compilan con make:
# los compilan las pruebas, y ustedes, con los comandos de los apuntes.

CC = gcc
CFLAGS = -Wall -Wextra -std=c17 -g -fsanitize=address,undefined
BUILD = build
PROGRAMS = function_pointer repeated_loops prices sort_students sort_names any_sort \
           search_students for_each calculator permutations

LAB_HEADERS = lab/compare.h lab/array_ops.h lab/backtrack.h lab/queens.h lab/board.h lab/sudoku.h
LAB_PROGRAMS = sort_trips ops_tests coloring queens_main sudoku_main

.PHONY: all lab solution test test-lab clean

all: $(PROGRAMS:%=$(BUILD)/%)

$(BUILD)/%: %.c | $(BUILD)
	$(CC) $(CFLAGS) $< -o $@

# Cada .c se compila por separado y luego se enlaza, como en la semana 6.
$(BUILD)/lab/%.o: lab/%.c $(LAB_HEADERS) | $(BUILD)/lab
	$(CC) $(CFLAGS) -c $< -o $@

$(BUILD)/lab/sort_trips: $(BUILD)/lab/sort_trips.o $(BUILD)/lab/compare.o
	$(CC) $(CFLAGS) $^ -o $@

$(BUILD)/lab/ops_tests: $(BUILD)/lab/ops_tests.o $(BUILD)/lab/array_ops.o
	$(CC) $(CFLAGS) $^ -o $@

$(BUILD)/lab/coloring: $(BUILD)/lab/coloring.o $(BUILD)/lab/backtrack.o
	$(CC) $(CFLAGS) $^ -o $@

$(BUILD)/lab/queens_main: $(BUILD)/lab/queens_main.o $(BUILD)/lab/queens.o $(BUILD)/lab/backtrack.o
	$(CC) $(CFLAGS) $^ -o $@

$(BUILD)/lab/sudoku_main: $(BUILD)/lab/sudoku_main.o $(BUILD)/lab/sudoku.o $(BUILD)/lab/board.o $(BUILD)/lab/backtrack.o
	$(CC) $(CFLAGS) $^ -o $@

# La solución trae solo lo que ustedes escriben. Lo demás se toma de lab/.
$(BUILD)/solution/%.o: solution/%.c $(LAB_HEADERS) | $(BUILD)/solution
	$(CC) $(CFLAGS) -Ilab -c $< -o $@

$(BUILD)/solution/%.o: lab/%.c $(LAB_HEADERS) | $(BUILD)/solution
	$(CC) $(CFLAGS) -Ilab -c $< -o $@

$(BUILD)/solution/sort_trips: $(BUILD)/solution/sort_trips.o $(BUILD)/solution/compare.o
	$(CC) $(CFLAGS) $^ -o $@

$(BUILD)/solution/ops_tests: $(BUILD)/solution/ops_tests.o $(BUILD)/solution/array_ops.o
	$(CC) $(CFLAGS) $^ -o $@

$(BUILD)/solution/coloring: $(BUILD)/solution/coloring.o $(BUILD)/solution/backtrack.o
	$(CC) $(CFLAGS) $^ -o $@

$(BUILD)/solution/queens_main: $(BUILD)/solution/queens_main.o $(BUILD)/solution/queens.o $(BUILD)/solution/backtrack.o
	$(CC) $(CFLAGS) $^ -o $@

$(BUILD)/solution/sudoku_main: $(BUILD)/solution/sudoku_main.o $(BUILD)/solution/sudoku.o $(BUILD)/solution/board.o $(BUILD)/solution/backtrack.o
	$(CC) $(CFLAGS) $^ -o $@

$(BUILD) $(BUILD)/lab $(BUILD)/solution:
	mkdir -p $@

lab: $(LAB_PROGRAMS:%=$(BUILD)/lab/%)

solution: $(LAB_PROGRAMS:%=$(BUILD)/solution/%)

# Si existe solution/, también se comprueba la solución del laboratorio.
test: all
	@if [ -d solution ]; then $(MAKE) --no-print-directory solution; fi
	python3 -m unittest discover -p 'test_*.py'

test-lab: all lab
	LAB_DIR=lab python3 -m unittest -v test_lab

clean:
	rm -rf $(BUILD) __pycache__
