#!/bin/bash
# ==========================================
# AEA SERVER MODULE: MATRIX BRIDGES
# VERSION: 1.26 (MAXIMUM VERBOSE LOGGING & TIMEOUTS)
# ==========================================
AEA_VERSION="1.26"
DOMAIN="{{MATRIX_DOMAIN}}"
ENGINE="{{MATRIX_ENGINE}}"
LOG_FILE="/var/log/aea_bridges_install.log"

AEA_MIRROR_URL="{{AEA_MIRROR_URL}}"
if [[ "$AEA_MIRROR_URL" == "{{"* ]]; then
    AEA_MIRROR_URL="https://download.aea-aiserver.ru/mirror"
fi

if [ "$1" == "--version" ] || [ "$1" == "-v" ]; then echo "$AEA_VERSION"; exit 0; fi

if [ "$ENGINE" == "synapse" ]; then
    MATRIX_PORT=6168
    MATRIX_DATA_DIR="/opt/aea_matrix_synapse/data"
    MATRIX_CONTAINER="aea_matrix_synapse"
else
    MATRIX_PORT=6167
    MATRIX_DATA_DIR="/opt/aea_matrix"
    MATRIX_CONTAINER="aea_matrix_conduit"
fi

# Функция логирования с таймстемпами
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

if [ "$1" == "--remove" ]; then
    BRIDGE_NAME=$2
    log "Starting removal of $BRIDGE_NAME"
    if [ -n "$BRIDGE_NAME" ]; then
        docker stop "aea_bridge_$BRIDGE_NAME" >/dev/null 2>&1
        docker rm -f "aea_bridge_$BRIDGE_NAME" >/dev/null 2>&1
        rm -rf "/opt/aea_matrix/bridges/$BRIDGE_NAME"
    fi
    exit 0
fi

install_bridge() {
    local BRIDGE_NAME=$1
    local TOKEN="${BRIDGE_TOKEN:-}"
    
    # === ВКЛЮЧАЕМ РЕЖИМ ГЛУБОКОЙ ОТЛАДКИ BASH ===
    # Все команды и их результаты теперь пишутся в лог
    exec >> "$LOG_FILE" 2>&1
    set -x

    log "=========================================="
    log "[AEA] Deploying integration module: $BRIDGE_NAME for engine: $ENGINE"
    BASE_DIR="/opt/aea_matrix/bridges/$BRIDGE_NAME"
    mkdir -p "$BASE_DIR"

    case "$BRIDGE_NAME" in
        telegram) IMAGE="dock.mau.dev/mautrix/telegram:latest"; BIN="mautrix-telegram"; PORT=29317 ;;
        whatsapp) IMAGE="dock.mau.dev/mautrix/whatsapp:latest"; BIN="mautrix-whatsapp"; PORT=29318 ;;
        discord)  IMAGE="dock.mau.dev/mautrix/discord:latest";  BIN="mautrix-discord"; PORT=29319 ;;
        *) log "[AEA] Unknown module: $BRIDGE_NAME"; exit 1 ;;
    esac

    TAR_FILE="mautrix_bridges_pack.tar.gz"
    
    log "[STEP 1] Checking if Docker image exists..."
    if ! docker image inspect "$IMAGE" >/dev/null 2>&1; then
        log "[STEP 1.1] Image not found. Trying to download archive $TAR_FILE from $AEA_MIRROR_URL"
        
        # Устанавливаем жесткий таймаут на проверку зеркала (10 секунд)
        if timeout 10s wget -q --spider "$AEA_MIRROR_URL/$TAR_FILE"; then
            log "[STEP 1.2] Archive found. Downloading..."
            # Таймаут на скачивание 2 минуты
            timeout 120s wget -qO "/tmp/$TAR_FILE" "$AEA_MIRROR_URL/$TAR_FILE"
            
            log "[STEP 1.3] Loading archive to Docker..."
            # Таймаут на распаковку 3 минуты
            timeout 180s docker load -i "/tmp/$TAR_FILE"
            rm -f "/tmp/$TAR_FILE"
        else
            log "[STEP 1.2] Archive not found or mirror offline. Falling back to direct docker pull..."
            timeout 180s docker pull "$IMAGE"
        fi
    else
        log "[STEP 1] Image $IMAGE already exists locally."
    fi

    log "[STEP 2] Extracting native configuration for $BRIDGE_NAME..."
    # Если запуск без параметров висит, принудительно обрываем через 15 секунд
    timeout 15s docker run --rm -v "$BASE_DIR:/data" "$IMAGE" || true

    log "[STEP 3] Running Python script to update config.yaml..."
    cat <<EOF > "$BASE_DIR/update_config.py"
import yaml

def process_data(data):
    if isinstance(data, dict):
        for k, v in data.items():
            if k == 'api_id': data[k] = 17359
            elif k == 'api_hash': data[k] = '344583e45741c457fe1862106095a5eb'
            elif v == 'unconfigured': data[k] = ''
            else: process_data(v)
    elif isinstance(data, list):
        for item in data: process_data(item)

try:
    with open('config.yaml', 'r') as f:
        config = yaml.safe_load(f) or {}
except: config = {}

process_data(config)

for key in ['homeserver', 'appservice', 'bridge', 'database']:
    if key not in config or not isinstance(config[key], dict):
        config[key] = {}

config['homeserver']['domain'] = '$DOMAIN'
config['homeserver']['address'] = 'http://172.17.0.1:$MATRIX_PORT'

config['appservice']['address'] = 'http://172.17.0.1:$PORT'
config['appservice']['hostname'] = '0.0.0.0'
config['appservice']['port'] = $PORT

if 'db' in config and isinstance(config['db'], dict):
    config['db']['type'] = 'sqlite3-fk-wal'
    config['db']['uri'] = 'file:/data/database.db?_txlock=immediate'
    if 'database' in config: del config['database']
else:
    config['database']['type'] = 'sqlite3-fk-wal'
    config['database']['uri'] = 'file:/data/database.db?_txlock=immediate'

if 'permissions' not in config['bridge'] or not isinstance(config['bridge']['permissions'], dict):
    config['bridge']['permissions'] = {}

config['bridge']['permissions']['$DOMAIN'] = 'admin'
config['bridge']['permissions']['@admin:$DOMAIN'] = 'admin'

if '$BRIDGE_NAME' == 'telegram' and 'telegram' in config: del config['telegram']
if '$BRIDGE_NAME' == 'discord' and 'discord' in config: del config['discord']

with open('config.yaml', 'w') as f:
    yaml.dump(config, f, default_flow_style=False)
EOF

    cd "$BASE_DIR"
    python3 update_config.py
    rm -f update_config.py

    log "[STEP 4] Injecting TOKEN into config.yaml..."
    if [ "$BRIDGE_NAME" == "telegram" ]; then
        echo "telegram:" >> "$BASE_DIR/config.yaml"
        echo "  api_id: 17359" >> "$BASE_DIR/config.yaml"
        echo "  api_hash: 344583e45741c457fe1862106095a5eb" >> "$BASE_DIR/config.yaml"
        echo "  bot_token: \"$TOKEN\"" >> "$BASE_DIR/config.yaml"
        echo "  device_info:" >> "$BASE_DIR/config.yaml"
        echo "    device_model: Mautrix-Telegram" >> "$BASE_DIR/config.yaml"
        echo "    system_version: Linux" >> "$BASE_DIR/config.yaml"
        echo "    app_version: 0.13.0" >> "$BASE_DIR/config.yaml"
    elif [ "$BRIDGE_NAME" == "discord" ]; then
        echo "discord:" >> "$BASE_DIR/config.yaml"
        echo "  token: \"$TOKEN\"" >> "$BASE_DIR/config.yaml"
    fi

    log "[STEP 5] Generating appservice registration for $BRIDGE_NAME..."
    timeout 30s docker run --rm -v "$BASE_DIR:/data" "$IMAGE" $BIN -g -c /data/config.yaml -r /data/registration.yaml

    log "[STEP 6] Syncing registration with Matrix Engine ($ENGINE)..."
    if [ -f "$BASE_DIR/registration.yaml" ]; then
        if [ "$ENGINE" == "synapse" ]; then
            cp "$BASE_DIR/registration.yaml" "$MATRIX_DATA_DIR/${BRIDGE_NAME}_registration.yaml"
            chmod 644 "$MATRIX_DATA_DIR/${BRIDGE_NAME}_registration.yaml"
            if ! grep -q "${BRIDGE_NAME}_registration.yaml" "$MATRIX_DATA_DIR/homeserver.yaml"; then
                if grep -q "^app_service_config_files:" "$MATRIX_DATA_DIR/homeserver.yaml"; then
                    sed -i "/^app_service_config_files:/a \ \ - /data/${BRIDGE_NAME}_registration.yaml" "$MATRIX_DATA_DIR/homeserver.yaml"
                else
                    echo -e "\napp_service_config_files:\n  - /data/${BRIDGE_NAME}_registration.yaml" >> "$MATRIX_DATA_DIR/homeserver.yaml"
                fi
            fi
            docker restart $MATRIX_CONTAINER
        fi
    fi

    log "[STEP 7] Starting background container for $BRIDGE_NAME..."
    docker stop "aea_bridge_$BRIDGE_NAME" >/dev/null 2>&1 || true
    docker rm -f "aea_bridge_$BRIDGE_NAME" >/dev/null 2>&1 || true
    
    # Запускаем контейнер в фоне
    docker run -d --name "aea_bridge_$BRIDGE_NAME" --restart unless-stopped \
      -p $PORT:$PORT \
      -v "$BASE_DIR:/data" \
      "$IMAGE"
      
    log "[STEP 8] Installation script finished successfully."
    
    # Отключаем дебаг перед выходом
    set +x
}

if [ "$1" == "--install" ]; then
    # Очищаем старый лог перед новой установкой
    echo "" > "$LOG_FILE"
    install_bridge "$2"
    exit 0
fi

MODULE_PATH="/usr/local/bin/aea_matrix_bridges"
cat "$0" > "$MODULE_PATH"
chmod +x "$MODULE_PATH"

exit 0
