CC?=clang

FIND=$(shell which gfind find | head -1)

UNAME_S:=$(shell uname -s)
UNAME_M:=$(shell uname -m)

VERSION?=0.1.0

SRC:=
INCLUDES:=
CFLAGS:=
LDFLAGS:=
DESTDIR?=/usr/local

ifeq ($(UNAME_S),Darwin)
  OBJCOPY:=$(shell echo "echo 'Not using objcopy'")
  LD:=$(shell which ld)
  LICENSE_OBJ:=license.c
  LDFLAGS+=-lobjc
else
  OBJCOPY?=objcopy
  OBJCOPY:=$(shell which objcopy)
  LICENSE_OBJ:=license.o
endif

ARCH_TARGET?=$(shell echo $(UNAME_M) | sed -e 's/x86_64/elf64-x86-64/' -e 's/arm64/elf64-littleaarch64/' -e 's/aarch64/elf64-littleaarch64/')
ARCH_BIN?=$(shell echo $(UNAME_M) | sed -e 's/x86_64/i386/' -e 's/arm64/aarch64/' -e 's/aarch64/aarch64/')

SRC+=$(shell $(FIND) src/ -type f -name '*.c')
INCLUDES+=-Isrc
INCLUDES+=-Ilib/.dep/include

LIBS:=

LIBS+=lib/cofyc/argparse
SRC+=lib/cofyc/argparse/argparse.c

LIBS+=lib/cozis/tinytemplate
SRC+=lib/cozis/tinytemplate/src/tinytemplate.c

LIBS+=lib/emmanuel-marty/em_inflate
SRC+=lib/emmanuel-marty/em_inflate/lib/em_inflate.c

LIBS+=lib/erkkah/naett
SRC+=lib/erkkah/naett/naett.c
LDFLAGS+=-lcurl -lpthread

LIBS+=lib/rxi/microtar
SRC+=lib/rxi/microtar/src/microtar.c

LIBS+=lib/tidwall/json.c
SRC+=lib/tidwall/json.c/json.c

OBJ:=$(SRC:.c=.o)
OBJ:=$(OBJ:.cc=.o)
OBJ+=$(LICENSE_OBJ)

CFLAGS+=${INCLUDES}
CFLAGS+=-DDEP_VERSION=\"$(VERSION)\"

.PHONY: default
default: dep

.PHONY: FORCE
FORCE:

license.o: LICENSE.md
	$(OBJCOPY) --input binary --output $(ARCH_TARGET) --binary-architecture $(ARCH_BIN) $< $@

license.c: LICENSE.md
	(echo "static const unsigned char _license_md_data[] = {"; xxd -i < LICENSE.md; echo "};") > license.c
	(echo "static const unsigned char * const _license_md_end = _license_md_data + sizeof(_license_md_data);" >> license.c)
	(echo "const unsigned char * const _binary_LICENSE_md_start = _license_md_data;" >> license.c)
	(echo "const unsigned char * const _binary_LICENSE_md_end = _license_md_end;" >> license.c)

lib/cofyc/argparse:
	mkdir -p lib/cofyc/argparse
	curl -sL https://github.com/cofyc/argparse/archive/refs/heads/master.tar.gz | tar xzv --strip-components=1 -C lib/cofyc/argparse
	mkdir -p lib/.dep/include/cofyc
	ln -s ../../../cofyc/argparse/argparse.h lib/.dep/include/cofyc/argparse.h

lib/cozis/tinytemplate:
	mkdir -p lib/cozis/tinytemplate
	curl -sL https://github.com/cozis/tinytemplate/archive/refs/heads/main.tar.gz | tar xzv --strip-components=1 -C lib/cozis/tinytemplate
	mkdir -p lib/.dep/include/cozis
	ln -s ../../../cozis/tinytemplate/src/tinytemplate.h lib/.dep/include/cozis/tinytemplate.h

lib/emmanuel-marty/em_inflate:
	mkdir -p lib/emmanuel-marty/em_inflate
	curl -sL https://github.com/emmanuel-marty/em_inflate/archive/refs/heads/master.tar.gz | tar xzv --strip-components=1 -C lib/emmanuel-marty/em_inflate
	mkdir -p lib/.dep/include/emmanuel-marty
	ln -s ../../../emmanuel-marty/em_inflate/lib/em_inflate.h lib/.dep/include/emmanuel-marty/em_inflate.h

lib/erkkah/naett:
	mkdir -p lib/erkkah/naett
	curl -sL https://github.com/erkkah/naett/archive/refs/heads/main.tar.gz | tar xzv --strip-components=1 -C lib/erkkah/naett
	mkdir -p lib/.dep/include/erkkah
	ln -s ../../../erkkah/naett/naett.h lib/.dep/include/erkkah/naett.h

lib/rxi/microtar:
	mkdir -p lib/rxi/microtar
	curl -sL https://github.com/rxi/microtar/archive/refs/heads/master.tar.gz | tar xzv --strip-components=1 -C lib/rxi/microtar
	mkdir -p lib/.dep/include/rxi
	ln -s ../../../rxi/microtar/src/microtar.h lib/.dep/include/rxi/microtar.h

lib/tidwall/json.c:
	mkdir -p lib/tidwall/json.c
	curl -sL https://github.com/tidwall/json.c/archive/refs/heads/main.tar.gz | tar xzv --strip-components=1 -C lib/tidwall/json.c
	mkdir -p lib/.dep/include/tidwall
	ln -s ../../../tidwall/json.c/json.h lib/.dep/include/tidwall/json.h

.c.o:
	${CC} $< ${CFLAGS} -c -o $@

# Tracks the version we last built with, only rewritten when it actually
# changes, so overriding VERSION on the command line rebuilds what it should
.version: FORCE
	@echo '$(VERSION)' | cmp -s - $@ || echo '$(VERSION)' > $@

# Bakes in DEP_VERSION, so it must follow changes to VERSION
src/command/version/main.o: .version

dep: $(LIBS) $(OBJ)
	${CC} ${OBJ} ${CFLAGS} ${LDFLAGS} -o dep
	strip -u -r dep 2>/dev/null || true

.PHONY: install
install: dep
	install dep ${DESTDIR}/bin

.PHONY: clean
clean:
	rm -f $(OBJ) .version

.PHONY: format
format:
	$(FIND) src/ -type f \( -name '*.c' -o -name '*.h' \) -exec clang-format -i {} +
