#!/opt/local/bin/bash
# Mole - Common Functions Library
# Main entry point that loads all core modules

set -euo pipefail

# Prevent multiple sourcing
if [[ -n "${MOLE_COMMON_LOADED:-}" ]]; then
    return 0
fi
readonly MOLE_COMMON_LOADED=1

_MOLE_CORE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# Load core modules
source "$_MOLE_CORE_DIR/base.sh"
source "$_MOLE_CORE_DIR/log.sh"

source "$_MOLE_CORE_DIR/timeout.sh"
source "$_MOLE_CORE_DIR/file_ops.sh"
source "$_MOLE_CORE_DIR/ui.sh"
source "$_MOLE_CORE_DIR/app_protection.sh"

# Load sudo management if available
if [[ -f "$_MOLE_CORE_DIR/sudo.sh" ]]; then
    source "$_MOLE_CORE_DIR/sudo.sh"
fi

# Update via Homebrew
update_via_homebrew() {
    local current_version="$1"
    local temp_update temp_upgrade
    temp_update=$(mktemp_file "brew_update")
    temp_upgrade=$(mktemp_file "brew_upgrade")

    # Set up trap for interruption (Ctrl+C) with inline cleanup
    trap 'stop_inline_spinner 2>/dev/null; rm -f "$temp_update" "$temp_upgrade" 2>/dev/null; echo ""; exit 130' INT TERM

    # Update Homebrew
    if [[ -t 1 ]]; then
        start_inline_spinner "Updating Homebrew..."
    else
        echo "Updating Homebrew..."
    fi

    brew update > "$temp_update" 2>&1 &
    local update_pid=$!
    wait $update_pid 2> /dev/null || true # Continue even if brew update fails

    if [[ -t 1 ]]; then
        stop_inline_spinner
    fi

    # Upgrade Mole
    if [[ -t 1 ]]; then
        start_inline_spinner "Upgrading Mole..."
    else
        echo "Upgrading Mole..."
    fi

    brew upgrade mole > "$temp_upgrade" 2>&1 &
    local upgrade_pid=$!
    wait $upgrade_pid 2> /dev/null || true # Continue even if brew upgrade fails

    local upgrade_output
    upgrade_output=$(cat "$temp_upgrade")

    if [[ -t 1 ]]; then
        stop_inline_spinner
    fi

    # Clear trap
    trap - INT TERM

    # Cleanup temp files
    rm -f "$temp_update" "$temp_upgrade"

    if echo "$upgrade_output" | grep -q "already installed"; then
        local installed_version
        installed_version=$(brew list --versions mole 2> /dev/null | awk '{print $2}')
        echo ""
        echo -e "${GREEN}${ICON_SUCCESS}${NC} Already on latest version (${installed_version:-$current_version})"
        echo ""
    elif echo "$upgrade_output" | grep -q "Error:"; then
        log_error "Homebrew upgrade failed"
        echo "$upgrade_output" | grep "Error:" >&2
        return 1
    else
        echo "$upgrade_output" | grep -Ev "^(==>|Updating Homebrew|Warning:)" || true
        local new_version
        new_version=$(brew list --versions mole 2> /dev/null | awk '{print $2}')
        echo ""
        echo -e "${GREEN}${ICON_SUCCESS}${NC} Updated to latest version (${new_version:-$current_version})"
        echo ""
    fi

    # Clear update cache (suppress errors if cache doesn't exist or is locked)
    rm -f "$HOME/.cache/mole/version_check" "$HOME/.cache/mole/update_message" 2> /dev/null || true
}

# Remove applications from Dock
remove_apps_from_dock() {
    if [[ $# -eq 0 ]]; then
        return 0
    fi

    local plist="$HOME/Library/Preferences/com.apple.dock.plist"
    [[ -f "$plist" ]] || return 0

    if ! command -v python3 > /dev/null 2>&1; then
        return 0
    fi

    # Prune dock entries using Python helper
    python3 - "$@" << 'PY' 2> /dev/null || return 0
import os
import plistlib
import subprocess
import sys
import urllib.parse

plist_path = os.path.expanduser('~/Library/Preferences/com.apple.dock.plist')
if not os.path.exists(plist_path):
    sys.exit(0)

def normalise(path):
    if not path:
        return ''
    return os.path.normpath(os.path.realpath(path.rstrip('/')))

targets = {normalise(arg) for arg in sys.argv[1:] if arg}
targets = {t for t in targets if t}
if not targets:
    sys.exit(0)

with open(plist_path, 'rb') as fh:
    try:
        data = plistlib.load(fh)
    except Exception:
        sys.exit(0)

apps = data.get('persistent-apps')
if not isinstance(apps, list):
    sys.exit(0)

changed = False
filtered = []
for item in apps:
    try:
        url = item['tile-data']['file-data']['_CFURLString']
    except (KeyError, TypeError):
        filtered.append(item)
        continue

    if not isinstance(url, str):
        filtered.append(item)
        continue

    parsed = urllib.parse.urlparse(url)
    path = urllib.parse.unquote(parsed.path or '')
    if not path:
        filtered.append(item)
        continue

    candidate = normalise(path)
    if any(candidate == t or candidate.startswith(t + os.sep) for t in targets):
        changed = True
        continue

    filtered.append(item)

if not changed:
    sys.exit(0)

data['persistent-apps'] = filtered
with open(plist_path, 'wb') as fh:
    try:
        plistlib.dump(data, fh, fmt=plistlib.FMT_BINARY)
    except Exception:
        plistlib.dump(data, fh)

# Restart Dock to apply changes
try:
    subprocess.run(['killall', 'Dock'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False)
except Exception:
    pass
PY
}
