#!/bin/bash
#
# gen-management-settings-reconcile: Inotify-driven reconciliation service
# Ensures target config files match source files based on SOURCE_MODE
#

set -euo pipefail

CONFIG_FILE="/etc/default/gen-management-settings"
LOCK_FILE="/run/gen-management-settings/reconcile.lock"
LOG_TAG="gen-management-settings"

# Ensure lock directory exists
mkdir -p "$(dirname "$LOCK_FILE")"

# Prevent concurrent reconciliation
if [ -f "$LOCK_FILE" ]; then
    LOCK_PID=$(cat "$LOCK_FILE" 2>/dev/null || echo "")
    if kill -0 "$LOCK_PID" 2>/dev/null; then
        exit 0
    fi
    rm -f "$LOCK_FILE"
fi

echo $$ > "$LOCK_FILE"
trap "rm -f '$LOCK_FILE'" EXIT

# Load configuration
if [ ! -f "$CONFIG_FILE" ]; then
    echo "$LOG_TAG: Config file not found: $CONFIG_FILE" | \
        systemd-cat -t "$LOG_TAG" -p err
    exit 1
fi

source "$CONFIG_FILE"

: "${SOURCE_MODE:?ERROR: SOURCE_MODE not set}"
: "${MANAGED_ITEMS:?ERROR: MANAGED_ITEMS not set}"

UPDATED_COUNT=0
ERROR_COUNT=0

# Reconcile a single item
reconcile_item() {
    local item="$1"
    local source_var="${item^^}_SOURCE_DIR"
    local target_var="${item^^}_TARGET_FILE"
    local perms_var="${item^^}_TARGET_PERMISSIONS"

    local source_dir="${!source_var:-}"
    local target_file="${!target_var:-}"
    local target_perms="${!perms_var:-0644}"

    if [ -z "$source_dir" ] || [ -z "$target_file" ]; then
        return 1
    fi

    # Construct source path
    local source_file="$source_dir/$SOURCE_MODE/$item.json"

    # Special case: Claude uses managed-settings.json
    if [ "$item" = "claude" ]; then
        source_file="$source_dir/$SOURCE_MODE/managed-settings.json"
    fi

    if [ ! -f "$source_file" ]; then
        echo "$LOG_TAG: Source not found: $source_file" | \
            systemd-cat -t "$LOG_TAG" -p err
        return 1
    fi

    # Create target directory if needed
    target_dir=$(dirname "$target_file")
    mkdir -p "$target_dir"

    # Compare hashes
    local source_hash=$(sha256sum "$source_file" | cut -d' ' -f1)
    local target_hash=""

    if [ -f "$target_file" ]; then
        target_hash=$(sha256sum "$target_file" | cut -d' ' -f1)
    else
        target_hash="MISSING"
    fi

    if [ "$source_hash" != "$target_hash" ]; then
        # Backup existing
        if [ -f "$target_file" ]; then
            cp "$target_file" "$target_file.backup.$(date +%s)"
            ls -t "$target_file".backup.* 2>/dev/null | tail -n +6 | xargs -r rm
        fi

        # Deploy
        cp "$source_file" "$target_file"
        chmod "$target_perms" "$target_file"

        echo "$LOG_TAG: Updated $item (mode: $SOURCE_MODE)" | \
            systemd-cat -t "$LOG_TAG" -p info

        UPDATED_COUNT=$((UPDATED_COUNT + 1))
    fi

    return 0
}

# Process each item
for item in ${MANAGED_ITEMS//,/ }; do
    item=$(echo "$item" | xargs)
    if ! reconcile_item "$item"; then
        ERROR_COUNT=$((ERROR_COUNT + 1))
    fi
done

if [ $ERROR_COUNT -gt 0 ]; then
    exit 1
fi

exit 0