# Semana 2: principios de diseño y sockets en C. Se usa dentro del contenedor del
# curso (env/run.sh).
#
#   make           compila los programas de la clase en build/
#   make test      corre las pruebas y destruye lo que hayan levantado, aunque
#                  alguna falle (incluye una topología: toma alrededor de un minuto)
#   make test-lab  prueba su laboratorio (lab/*.c); falla hasta que lo terminen
#   make deploy    levanta la topología fate.clab.yml
#   make destroy   la destruye y borra su red de Docker
#   make clean     borra lo generado y destruye la topología

CC = gcc
CFLAGS = -Wall -Wextra -std=c17 -g -I.
BUILD = build
STATIC = $(BUILD)/static
TOPOLOGY = fate.clab.yml
NETWORK = redes-w02
LAB_PROGRAMS = wc_big_client wc_counting_server wcf_server wcf_client \
               wc_udp_server wc_udp_client room_server
PROGRAMS = byte_order flaky_relay reuse_demo short_send chunk_send chunk_recv \
           wc_server wc_client wc_fork_server tally_server \
           time_server time_client seq_send seq_recv
# Corren dentro de los nodos de la topología: la imagen de los routers usa otra
# biblioteca de C, así que van estáticos.
STATIC_PROGRAMS = chunk_send chunk_recv seq_send seq_recv
COMMON = io_util.c wc_service.c
HEADERS = io_util.h wc_service.h

.PHONY: all lab test test-lab deploy destroy clean

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

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

$(STATIC)/%: %.c io_util.c io_util.h | $(STATIC)
	$(CC) $(CFLAGS) -static -o $@ $< io_util.c

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

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

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

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

# Si existe solution/, también se comprueba la solución del laboratorio.
test: all
	@if [ -d solution ]; then $(MAKE) --no-print-directory \
	  $(LAB_PROGRAMS:%=$(BUILD)/solution/%); fi
	@rc=0; python3 -m unittest discover -v -p 'test_*.py' || rc=$$?; \
	  $(MAKE) --no-print-directory destroy; exit $$rc

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

deploy: all
	containerlab deploy --reconfigure -t $(TOPOLOGY)

destroy:
	@containerlab destroy -t $(TOPOLOGY) --cleanup >/dev/null 2>&1 || true
	@docker network rm $(NETWORK) >/dev/null 2>&1 || true

clean: destroy
	rm -rf $(BUILD) __pycache__ clab-w02-fate .$(TOPOLOGY).bak
