# UNA CMS Development Makefile
# Configuration and helper variables
CACHE_DIRS := public/cache public/cache_public
LOG_DIR := public/logs
PRESERVE_FILES := .htaccess

# Colors for terminal output
GREEN := $(shell tput setaf 2 2>/dev/null || echo "")
YELLOW := $(shell tput setaf 3 2>/dev/null || echo "")
RED := $(shell tput setaf 1 2>/dev/null || echo "")
BOLD := $(shell tput bold 2>/dev/null || echo "")
RESET := $(shell tput sgr0 2>/dev/null || echo "")

# Define all phony targets (targets that don't produce files)
.PHONY: help clearcache clearlogs clearall k12map_clear_cache up stop down yarn bash db_show_master_status db_export_binlog_to_sql db_dump seed_accounts seed_persons seed_groups seed_all seed_clean test_php test_php_coverage install_modules uninstall_modules enable_modules disable_modules update_modules composer_install

# Default target when just running 'make'
help:
	@echo "$(BOLD)UNA CMS Development Commands$(RESET)"
	@echo "----------------------------"
	@echo "Available commands:"
	@echo "  $(YELLOW)make clearcache$(RESET)                   - Clear cache directories while preserving .htaccess files"
	@echo "  $(YELLOW)make clearlogs$(RESET)                    - Clear log files while preserving .htaccess file"
	@echo "  $(YELLOW)make clearall$(RESET)                     - Clear both cache and log files"
	@echo "  $(YELLOW)make k12map_clear_cache$(RESET)           - Clear K12 Map module's Friends Near Me cache tables"
	@echo "  $(YELLOW)make up$(RESET)                           - Start Docker containers in detached mode"
	@echo "  $(YELLOW)make stop$(RESET)                         - Stop Docker containers"
	@echo "  $(YELLOW)make down$(RESET)                    		- Stop and remove Docker containers."
	@echo "  $(YELLOW)make bash$(RESET)                         - Open interactive bash shell in PHP container at /var/www"
	@echo "  $(YELLOW)make yarn$(RESET)                         - Run yarn commands in the node container"
	@echo "  $(YELLOW)make db_show_master_status$(RESET)        - Show the master status of the database"
	@echo "  $(YELLOW)make db_export_binlog_to_sql <start> <end>$(RESET) - Export specific binlog range to executable_changes.sql"
	@echo "  $(YELLOW)make db_dump$(RESET)                       - Dump full 'una' DDL + data except selected sensitive/volatile tables"
	@echo "  $(YELLOW)make seed_accounts [COUNT=10]$(RESET)      - Create test accounts using Docker PHP container"
	@echo "  $(YELLOW)make seed_persons$(RESET)                  - Create person profiles for existing accounts using Docker PHP container"
	@echo "  $(YELLOW)make seed_groups [COUNT=3]$(RESET)         - Create groups and assign members using Docker PHP container"
	@echo "  $(YELLOW)make seed_all [COUNT=10]$(RESET)           - Run all seeders in sequence using Docker PHP container"
	@echo "  $(YELLOW)make seed_clean$(RESET)                    - Remove seed output files"
	@echo "  $(YELLOW)make composer_install$(RESET)              - Install Composer dependencies inside Docker PHP container"
	@echo "  $(YELLOW)make test_php$(RESET)                      - Run the root Pest test suite in the PHP container"
	@echo "  $(YELLOW)make test_php_coverage$(RESET)             - Run the root Pest suite with Clover coverage output"
	@echo "  $(YELLOW)make install_modules MODULE=<module>$(RESET)   - Install a module by name (e.g. stride/k12lcc)"
	@echo "  $(YELLOW)make uninstall_modules MODULE=<module>$(RESET) - Uninstall a module by name"
	@echo "  $(YELLOW)make enable_modules MODULE=<module>$(RESET)    - Enable a previously disabled module"
	@echo "  $(YELLOW)make disable_modules MODULE=<module>$(RESET)   - Disable an installed module without uninstalling"
	@echo "  $(YELLOW)make update_modules MODULE=<module>$(RESET)    - Run pending updates in the module's updates/ folder"

# UNA CMS Logs clearing command
clearlogs:
	@echo "$(GREEN)Clearing log files...$(RESET)"
	@echo "---------------------------"
	@if [ -d $(LOG_DIR) ]; then \
		echo "Cleaning $(LOG_DIR)..."; \
		find $(LOG_DIR) -type f -not -name "$(PRESERVE_FILES)" -delete && \
		echo "✓ $(LOG_DIR) cleared"; \
	else \
		echo "$(RED)⚠ Directory $(LOG_DIR) not found$(RESET)"; \
	fi
	@echo "---------------------------"
	@echo "$(GREEN)Logs clearing process complete.$(RESET)"

# UNA CMS Cache clearing command
clearcache:
	@echo "$(GREEN)Clearing cache directories...$(RESET)"
	@echo "---------------------------"
	@for dir in $(CACHE_DIRS); do \
		if [ -d $$dir ]; then \
			echo "Cleaning $$dir..."; \
			find $$dir -type f -not -name "$(PRESERVE_FILES)" -delete && \
			echo "✓ $$dir cleared"; \
		else \
			echo "$(RED)⚠ Directory $$dir not found$(RESET)"; \
		fi; \
	done
	@echo "---------------------------"
	@echo "$(GREEN)Cache clearing process complete.$(RESET)"

# Clear both cache and logs
clearall:
	@echo "$(GREEN)Running complete system cleanup...$(RESET)"
	@echo "============================"
	@$(MAKE) --no-print-directory -s clearcache
	@$(MAKE) --no-print-directory -s clearlogs
	@echo "============================"
	@echo "$(GREEN)Complete system cleanup finished.$(RESET)"

# Clear K12 Map module's Friends Near Me cache tables
k12map_clear_cache:
	@echo "$(GREEN)Clearing K12 Map Friends Near Me cache...$(RESET)"
	@echo "---------------------------"
	@docker compose exec -T mysql mariadb -u root -proot una -e " \
		SET @cache_count = (SELECT COUNT(*) FROM stride_k12map_cache); \
		SET @data_count = (SELECT COUNT(*) FROM stride_k12map_cache_data); \
		TRUNCATE TABLE stride_k12map_cache_data; \
		TRUNCATE TABLE stride_k12map_cache; \
		SELECT CONCAT('Deleted ', @cache_count, ' cache entries and ', @data_count, ' cache data records') AS Result; \
	" 2>/dev/null || echo "$(RED)Error: Could not connect to database$(RESET)"
	@echo "---------------------------"
	@echo "$(GREEN)K12 Map cache cleared. Next Friends Near Me request will fetch fresh data.$(RESET)"

# Start Docker containers in detached mode
up:
	@echo "$(GREEN)Starting Docker containers...$(RESET)"
	docker compose up -d
	@echo "$(GREEN)Containers started in detached mode.$(RESET)"

# Stop Docker containers
stop:
	@echo "$(GREEN)Stopping Docker containers...$(RESET)"
	docker compose stop
	@echo "$(GREEN)Containers stopped.$(RESET)"

# Stop and remove Docker containers
down:
	@echo "$(GREEN)Stopping Docker containers...$(RESET)"
	docker compose down
	@echo "$(GREEN)Containers stopped and removed.$(RESET)"

# Run yarn commands in the node container
yarn:
	@echo "$(GREEN)Running yarn commands...$(RESET)"
	@echo "1. Installing dependencies..."
	docker compose run --rm node yarn
	@echo "2. Building Tailwind CSS..."
	docker compose run --rm node yarn build:tailwind-custom
	@echo "$(GREEN)Yarn commands completed.$(RESET)"

# Show database master status
db_show_master_status:
	@echo "$(GREEN)Showing database master status...$(RESET)"
	docker compose exec -it mysql mariadb -u root -proot -e "SHOW MASTER STATUS;"

# Define make variables for arguments
# This ensures they are parsed by Make before any shell commands run.
_startPos := $(word 1,$(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS)))
_endPos := $(word 2,$(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS)))
_providedBinlogFile := $(word 3,$(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS)))

# Set default for binlog file if not provided using Make's conditional assignment
# The default is set to log_bin_file.000007, based on your `db_show_master_status` output.
BINLOG_FILE := $(if $(_providedBinlogFile),$(_providedBinlogFile),log_bin_file.000001)

# Export specific binlog range to SQL file
# Usage: make db_export_binlog_to_sql <startPos> <endPos> [binlogFile]
# Example: make db_export_binlog_to_sql 12345 67890 log_bin_file.000001
# Default binlogFile is log_bin_file.000001 if not specified.
db_export_binlog_to_sql:
	@if [ -z "$(_startPos)" ]; then \
		echo "$(RED)Error: <startPos> argument is missing. Usage: make db_export_binlog_to_sql <startPos> <endPos> [binlogFile]$(RESET)"; \
		exit 1; \
	fi
	@if [ -z "$(_endPos)" ]; then \
		echo "$(RED)Error: <endPos> argument is missing. Usage: make db_export_binlog_to_sql <startPos> <endPos> [binlogFile]$(RESET)"; \
		exit 1; \
	fi
	@if [ -z "$(_providedBinlogFile)" ]; then \
		echo "$(YELLOW)No binlog file specified. Using default: $(BINLOG_FILE)$(RESET)"; \
	fi
	@echo "$(GREEN)Exporting binlog from position $(_startPos) to $(_endPos) from $(BINLOG_FILE) to executable_changes.sql...$(RESET)"
	docker compose exec -T mysql mariadb-binlog --start-position=$(_startPos) --stop-position=$(_endPos) --base64-output=never /var/lib/mysql/$(BINLOG_FILE) \
	| grep -E "^#Q>|^ALTER TABLE " \
	| sed 's/^#Q> //' \
	| grep -v "UPDATE.*sys_cron_jobs" \
	| grep -v "UPDATE.*sys_options.*name.*sys_cron_time" \
	| grep -v "UPDATE.*sys_options.*name.*sys_eq_time" \
	| grep -v "UPDATE.*sys_options.*name.*sys_push_queue_time" \
	| grep -v "INSERT INTO.*sys_keys" \
	| sed 's/\([^;]\)$$/\1;/' \
	> executable_changes.sql
	@echo "$(GREEN)Binlog export complete. File saved as executable_changes.sql$(RESET)"

# Dump full 'una' DDL and data, excluding data for selected sensitive/volatile tables
db_dump:
	@$(eval DATE_STAMP := $(shell date +%d-%m-%Y))
	@$(eval FILENAME := ./docker/dumps/dev.setup.$(DATE_STAMP).sql)
	@echo "$(GREEN)Dumping full 'una' DDL plus selective data to $(FILENAME)...$(RESET)"
	docker compose exec -T mysql /usr/bin/mariadb-dump \
		-u root -proot \
		--databases una \
		--no-data \
		--routines \
		--events \
		--triggers \
		--add-drop-table \
		--create-options \
		--skip-set-charset \
		--default-character-set=utf8mb4 \
		> $(FILENAME)
	docker compose exec -T mysql /usr/bin/mariadb-dump \
		-u root -proot \
		una \
		--no-create-info \
		--skip-triggers \
		--ignore-table=una.sys_keys \
		--ignore-table=una.bx_messenger_jots \
		--ignore-table=una.bx_messenger_unread_jots \
		--ignore-table=una.bx_notifications_queue \
		--ignore-table=una.bx_oktacon_accounts \
		--ignore-table=una.sys_accounts_password \
		--ignore-table=una.sys_queue_email \
		--ignore-table=una.sys_queue_push \
		--ignore-table=una.sys_sessions \
		--ignore-table=una.sys_storage_deletions \
		--disable-keys \
		--lock-tables \
		--lock-all-tables \
		--extended-insert \
		--skip-set-charset \
		--default-character-set=utf8mb4 \
		>> $(FILENAME)
	@echo "$(GREEN)Database dump complete. File saved as $(FILENAME)$(RESET)"

# Seed commands using Docker PHP container
# Create test accounts
seed_accounts:
	@echo "$(GREEN)Creating test accounts using Docker PHP container...$(RESET)"
	@COUNT=$${COUNT:-10}; \
	PREFIX=$${PREFIX:-""}; \
	echo "Creating $$COUNT accounts with prefix '$$PREFIX'..."; \
	docker compose exec php php /var/www/seeds/entrypoint.php accounts $$COUNT 761 "$$PREFIX"
	@echo "$(GREEN)Account creation complete.$(RESET)"

# Create person profiles for existing accounts
seed_persons:
	@echo "$(GREEN)Creating person profiles using Docker PHP container...$(RESET)"
	@PREFIX=$${PREFIX:-""}; \
	echo "Creating profiles with prefix '$$PREFIX'..."; \
	docker compose exec php php /var/www/seeds/entrypoint.php persons 0 761 "$$PREFIX"
	@echo "$(GREEN)Person profile creation complete.$(RESET)"

# Create groups and assign members
seed_groups:
	@echo "$(GREEN)Creating groups using Docker PHP container...$(RESET)"
	@COUNT=$${COUNT:-3}; \
	PREFIX=$${PREFIX:-""}; \
	echo "Creating $$COUNT groups with prefix '$$PREFIX'..."; \
	docker compose exec php php /var/www/seeds/entrypoint.php groups $$COUNT 761 "$$PREFIX"
	@echo "$(GREEN)Group creation complete.$(RESET)"

# Run all seeders in sequence
seed_all:
	@echo "$(GREEN)Running all seeders using Docker PHP container...$(RESET)"
	@COUNT=$${COUNT:-10}; \
	PREFIX=$${PREFIX:-""}; \
	echo "Creating $$COUNT accounts, profiles, and groups with prefix '$$PREFIX'..."; \
	docker compose exec php php /var/www/seeds/entrypoint.php all $$COUNT 761 "$$PREFIX"
	@echo "$(GREEN)All seeding operations complete.$(RESET)"

# Remove seed output files
seed_clean:
	@echo "$(GREEN)Removing seed output files...$(RESET)"
	rm -f seeds/accounts/output.json seeds/persons/output.json seeds/groups/output.json
	@echo "$(GREEN)Seed output files removed.$(RESET)"

# Install Composer dependencies inside Docker PHP container
composer_install:
	@echo "$(GREEN)Installing Composer dependencies...$(RESET)"
	docker compose exec -T -w /var/www php composer install
	@echo "$(GREEN)Composer installation completed.$(RESET)"

# Run root Pest suite inside Docker PHP container
test_php:
	@echo "$(GREEN)Running root Pest test suite...$(RESET)"
	docker compose exec -T -w /var/www php composer test
	@echo "$(GREEN)Pest test suite completed.$(RESET)"

# Run root Pest suite with Clover coverage output inside Docker PHP container
test_php_coverage:
	@echo "$(GREEN)Running root Pest test suite with coverage...$(RESET)"
	docker compose exec -T -w /var/www php composer test:coverage
	@echo "$(GREEN)Pest coverage run completed. Report available at ci-reports/clover.xml$(RESET)"

# Install a module by name
# Usage: make install_modules MODULE=stride/k12lcc
install_modules:
	@if [ -z "$(MODULE)" ]; then \
		echo "$(RED)Error: MODULE parameter is required$(RESET)"; \
		echo "Usage: make install_modules MODULE=stride/k12lcc"; \
		exit 1; \
	fi
	@echo "$(GREEN)Installing module: $(MODULE)$(RESET)"
	@container_id=$$(docker compose ps -q php) && \
	docker exec -u www-data $$container_id php /var/www/manage.php -u /var/www/public -c install_modules -i -o $(MODULE)
	@echo "$(GREEN)Module installation complete.$(RESET)"

# Uninstall a module by name
# Usage: make uninstall_modules MODULE=stride/k12schooltag
uninstall_modules:
	@if [ -z "$(MODULE)" ]; then \
		echo "$(RED)Error: MODULE parameter is required$(RESET)"; \
		echo "Usage: make uninstall_modules MODULE=stride/k12schooltag"; \
		exit 1; \
	fi
	@echo "$(GREEN)Uninstalling module: $(MODULE)$(RESET)"
	@container_id=$$(docker compose ps -q php) && \
	docker exec -u www-data $$container_id php /var/www/manage.php -u /var/www/public -c uninstall_modules -i -o $(MODULE)
	@echo "$(GREEN)Module uninstallation complete.$(RESET)"

# Enable a previously disabled module
# Usage: make enable_modules MODULE=stride/k12lcc
enable_modules:
	@if [ -z "$(MODULE)" ]; then \
		echo "$(RED)Error: MODULE parameter is required$(RESET)"; \
		echo "Usage: make enable_modules MODULE=stride/k12lcc"; \
		exit 1; \
	fi
	@echo "$(GREEN)Enabling module: $(MODULE)$(RESET)"
	@container_id=$$(docker compose ps -q php) && \
	docker exec -u www-data $$container_id php /var/www/manage.php -u /var/www/public -c enable_modules -i -o $(MODULE)
	@echo "$(GREEN)Module enable complete.$(RESET)"

# Disable an installed module without uninstalling
# Usage: make disable_modules MODULE=stride/k12lcc
disable_modules:
	@if [ -z "$(MODULE)" ]; then \
		echo "$(RED)Error: MODULE parameter is required$(RESET)"; \
		echo "Usage: make disable_modules MODULE=stride/k12lcc"; \
		exit 1; \
	fi
	@echo "$(GREEN)Disabling module: $(MODULE)$(RESET)"
	@container_id=$$(docker compose ps -q php) && \
	docker exec -u www-data $$container_id php /var/www/manage.php -u /var/www/public -c disable_modules -i -o $(MODULE)
	@echo "$(GREEN)Module disable complete.$(RESET)"

# Run pending updates from the module's updates/ folder
# Usage: make update_modules MODULE=stride/k12lcc
update_modules:
	@if [ -z "$(MODULE)" ]; then \
		echo "$(RED)Error: MODULE parameter is required$(RESET)"; \
		echo "Usage: make update_modules MODULE=stride/k12lcc"; \
		exit 1; \
	fi
	@echo "$(GREEN)Updating module: $(MODULE)$(RESET)"
	@container_id=$$(docker compose ps -q php) && \
	docker exec -u www-data $$container_id php /var/www/manage.php -u /var/www/public -c update_modules -i -o $(MODULE)
	@echo "$(GREEN)Module update complete.$(RESET)"

# Open interactive bash shell in the PHP container
bash:
	@echo "$(GREEN)Opening interactive bash shell in PHP container at /var/www...$(RESET)"
	docker compose exec -it -w /var/www php bash
