DIST_DIR := dist
CRYSTAL_DIR := $(DIST_DIR)/crystal_palace
CRYSTAL_LINK := $(CRYSTAL_DIR)/link
PLUGIN_OUT := $(DIST_DIR)/crystal_forge.so

GO_PLUGIN_SOURCES := \
	pl_main.go \
	pl_packer.go \
	pl_utils.go \
	pl_sideloading.go

DIST_ASSETS := \
	$(DIST_DIR)/config.yaml \
	$(DIST_DIR)/ax_config.axs

# Full clean build
# Use this target when you want to rebuild everything from scratch.
all: clean crystal plugin loader beacon package-loader

# Development build
debug: crystal plugin loader-debug beacon package-loader-debug
	@echo " * Dev build completed (only modified files)"

# ==================== Crystal Palace Installation ====================
crystal: $(CRYSTAL_LINK)
	@echo " * Crystal Palace is ready"

$(CRYSTAL_LINK): | $(CRYSTAL_DIR)
	@echo " * Downloading Crystal Palace..."
	@curl -fsSL "https://tradecraftgarden.org/download/cpdist-latest.tgz" -o cpdist-latest.tgz
	@tar -xzf cpdist-latest.tgz -C $(CRYSTAL_DIR) --strip-components=1
	@rm -f cpdist-latest.tgz
	@echo "   done..."

# ==================== Build Go plugin ====================
plugin: $(PLUGIN_OUT) $(DIST_ASSETS)
	@echo " * Go plugin is up to date"

$(PLUGIN_OUT): $(GO_PLUGIN_SOURCES) | $(DIST_DIR)
	@echo " * Building crystal_forge Go plugin..."
	@GOEXPERIMENT=jsonv2,greenteagc go build \
		-buildmode=plugin \
		-ldflags="-s -w" \
		-o $@ \
		$(GO_PLUGIN_SOURCES)
	@echo "   done..."

$(DIST_DIR)/config.yaml: config.yaml | $(DIST_DIR)
	@cp -u $< $@

$(DIST_DIR)/ax_config.axs: ax_config.axs | $(DIST_DIR)
	@cp -u $< $@

# ==================== Build Beacon C++ ====================
beacon:
	@echo " * Building beacon C++ code..."
	@$(MAKE) -C src_beacon --no-print-directory \
		HTTP_DIST_DIR=../$(DIST_DIR)/objects_http \
		SMB_DIST_DIR=../$(DIST_DIR)/objects_smb \
		TCP_DIST_DIR=../$(DIST_DIR)/objects_tcp \
		DNS_DIST_DIR=../$(DIST_DIR)/objects_dns
	@echo "   done..."

loader:
	@echo " * Building Crystal loader..."
	@$(MAKE) -C loader --no-print-directory

loader-debug:
	@echo " * Building Crystal debug loader..."
	@$(MAKE) -C loader debug --no-print-directory

# Copy the loader tree into dist after its local build has completed so the
# packaged specs always point at the latest generated bin/ artifacts.
package-loader: loader | $(DIST_DIR)
	@rm -rf $(DIST_DIR)/loader
	@cp -r ./loader $(DIST_DIR)/loader

package-loader-debug: loader-debug | $(DIST_DIR)
	@rm -rf $(DIST_DIR)/loader
	@cp -r ./loader $(DIST_DIR)/loader

clean:
	@echo " * Cleaning build directories..."
	@rm -rf $(DIST_DIR)
	@$(MAKE) -C src_beacon --no-print-directory clean
	@$(MAKE) -C loader --no-print-directory clean

$(DIST_DIR):
	@mkdir -p $@

$(CRYSTAL_DIR):
	@mkdir -p $@

.PHONY: all debug crystal plugin loader loader-debug beacon package-loader package-loader-debug clean
