#!/bin/sh

export PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin"

REGISTRY_FILE="/calista/registry.db"
BUILTIN_FILE="/calista/builtin_devices"
DRIVER_INSTALLER="/calista/driver_installer"
DETECTED_DEVICES="/tmp/calista_detected_devices.tmp"

# Функция логирования
log_to_registry() {
    local type="$1"
    local details="$2"
    sqlite3 "$REGISTRY_FILE" "INSERT INTO calista_log (type, user, details)
                              VALUES ('$type', '$USER', '$details');" 2>/dev/null
}

# Проверяем, что реестр существует
if [ ! -f "$REGISTRY_FILE" ]; then
    echo "Ошибка: Реестр не найден: $REGISTRY_FILE"
    exit 1
fi

# Функция поиска устройства в файле builtin_devices
lookup_builtin_device() {
    local vendor="$1"
    local device="$2"
    if [ -f "$BUILTIN_FILE" ]; then
        grep -v "^ver" "$BUILTIN_FILE" 2>/dev/null | grep "^${vendor}:${device}:" | head -1
    fi
}

# Очищаем файл обнаруженных устройств
> "$DETECTED_DEVICES"

log_to_registry "info" "Запущено обновление списка устройств"

# -------------------------------------------------------------------
# 1. Сканирование PCI-устройств
# -------------------------------------------------------------------
echo "Сканирование PCI-устройств..."

pciconf -l | while read -r line; do
    DEV_NAME=$(echo "$line" | awk '{print $1}' | cut -d'@' -f1)

    VENDOR=$(echo "$line" | grep -o 'vendor=0x[0-9a-fA-F]*' | cut -d'=' -f2 | head -1)
    DEVICE=$(echo "$line" | grep -o 'device=0x[0-9a-fA-F]*' | cut -d'=' -f2 | head -1)
    SUBVENDOR=$(echo "$line" | grep -o 'subvendor=0x[0-9a-fA-F]*' | cut -d'=' -f2 | head -1)
    SUBDEVICE=$(echo "$line" | grep -o 'subdevice=0x[0-9a-fA-F]*' | cut -d'=' -f2 | head -1)
    CLASS=$(echo "$line" | grep -o 'class=0x[0-9a-fA-F]*' | cut -d'=' -f2 | head -1)

    if [ -z "$VENDOR" ] || [ -z "$DEVICE" ]; then
        continue
    fi

    echo "pci|$VENDOR|$DEVICE" >> "$DETECTED_DEVICES"

    CURRENT_STATUS=$(sqlite3 "$REGISTRY_FILE" "SELECT status FROM devices
                       WHERE bus='pci' AND vendor='$VENDOR' AND device='$DEVICE';" 2>/dev/null)

    BUILTIN_INFO=$(lookup_builtin_device "$VENDOR" "$DEVICE")

    if [ -n "$BUILTIN_INFO" ]; then
        DEVICE_NAME=$(echo "$BUILTIN_INFO" | cut -d':' -f3)
        DEVICE_TYPE=$(echo "$BUILTIN_INFO" | cut -d':' -f4)

        if [ "$DEVICE_TYPE" = "builtin" ]; then
            if [ "$DEV_NAME" != "none" ] && [ -n "$DEV_NAME" ]; then
                STATUS="installed"
                DRIVER="$DEV_NAME"
            else
                STATUS="builtin_available"
                DRIVER=""
            fi
        else
            if [ "$DEV_NAME" != "none" ] && [ -n "$DEV_NAME" ]; then
                STATUS="installed"
                DRIVER="$DEV_NAME"
            else
                STATUS="not_installed"
                DRIVER=""
            fi
        fi
    else
        DEVICE_NAME="Неизвестное устройство (Class: $CLASS)"
        DEVICE_TYPE="unknown"

        if [ "$DEV_NAME" != "none" ] && [ -n "$DEV_NAME" ]; then
            STATUS="installed"
            DRIVER="$DEV_NAME"
        else
            STATUS="not_installed"
            DRIVER=""
        fi
    fi

    # Проверяем, существует ли запись
    EXISTS=$(sqlite3 "$REGISTRY_FILE" "SELECT 1 FROM devices WHERE bus='pci' AND vendor='$VENDOR' AND device='$DEVICE';" 2>/dev/null)

    if [ -z "$EXISTS" ]; then
        # Новая запись
        sqlite3 "$REGISTRY_FILE" <<EOF
INSERT INTO devices (bus, vendor, device, subvendor, subdevice, name, status, driver, detected_at)
VALUES ('pci', '$VENDOR', '$DEVICE', '$SUBVENDOR', '$SUBDEVICE', '$DEVICE_NAME', '$STATUS', '$DRIVER', CURRENT_TIMESTAMP);
EOF
        echo "  PCI: $VENDOR:$DEVICE -> $DEVICE_NAME (статус: $STATUS) [НОВОЕ]"
    else
        # Обновляем только статус и driver, если они изменились и статус не calista
        if [ "$CURRENT_STATUS" != "installed_calista" ] && [ "$CURRENT_STATUS" != "installed_calista_error" ]; then
            sqlite3 "$REGISTRY_FILE" <<EOF
UPDATE devices SET status='$STATUS', driver='$DRIVER', detected_at=CURRENT_TIMESTAMP
WHERE bus='pci' AND vendor='$VENDOR' AND device='$DEVICE';
EOF
        fi
        echo "  PCI: $VENDOR:$DEVICE -> $DEVICE_NAME (статус: $STATUS) [ОБНОВЛЕНО]"
    fi

    # Логика установки драйвера
    if [ "$CURRENT_STATUS" != "installed_calista" ] && [ "$CURRENT_STATUS" != "installed_calista_error" ] && [ "$DEVICE_TYPE" != "builtin" ]; then
        echo "    -> Попытка установки через driver-installer..."

        if [ -x "$DRIVER_INSTALLER" ]; then
            "$DRIVER_INSTALLER" update_list > /dev/null 2>&1
            "$DRIVER_INSTALLER" get_name "$VENDOR" "$DEVICE" > /dev/null 2>&1
            DEVICE_CHECK=$("$DRIVER_INSTALLER" get_name "$VENDOR" "$DEVICE" 2>/dev/null)

            if [ "$DEVICE_CHECK" != "Неизвестное устройство" ] && [ -n "$DEVICE_CHECK" ]; then
                echo "    -> Найден драйвер: $DEVICE_CHECK"
                "$DRIVER_INSTALLER" install "$VENDOR" "$DEVICE"
            else
                echo "    -> Драйвер не найден в driver.list"
            fi
        fi
    elif [ "$CURRENT_STATUS" = "installed_calista" ]; then
        echo "    -> Уже установлен через Calista, пропускаем"
    elif [ "$DEVICE_TYPE" = "builtin" ]; then
        echo "    -> Встроен в ядро, установка не требуется"
    fi
done

# -------------------------------------------------------------------
# 2. Сканирование USB-устройств
# -------------------------------------------------------------------
echo "Сканирование USB-устройств..."

usbconfig list | grep -E "^ugen[0-9]+\.[0-9]+:" | while read -r line; do
    DEV_NAME=$(echo "$line" | awk '{print $1}' | cut -d':' -f1)

    if echo "$DEV_NAME" | grep -q "\.1$"; then
        continue
    fi

    DEV_INFO=$(usbconfig -d "$DEV_NAME" dump_device_desc 2>/dev/null)

    VENDOR=$(echo "$DEV_INFO" | grep "idVendor" | sed -E 's/.*idVendor *= *0x([0-9a-fA-F]+).*/0x\1/' | head -1)
    PRODUCT=$(echo "$DEV_INFO" | grep "idProduct" | sed -E 's/.*idProduct *= *0x([0-9a-fA-F]+).*/0x\1/' | head -1)

    if [ -z "$VENDOR" ] || [ -z "$PRODUCT" ]; then
        continue
    fi

    echo "usb|$VENDOR|$PRODUCT" >> "$DETECTED_DEVICES"

    BUILTIN_INFO=$(lookup_builtin_device "$VENDOR" "$PRODUCT")

    if [ -n "$BUILTIN_INFO" ]; then
        DEVICE_NAME=$(echo "$BUILTIN_INFO" | cut -d':' -f3)
        DEVICE_TYPE=$(echo "$BUILTIN_INFO" | cut -d':' -f4)
        STATUS="not_installed"
    else
        MANUFACTURER=$(echo "$DEV_INFO" | grep "iManufacturer" | head -1 | sed -E 's/.*<([^>]+)>.*/\1/')
        PRODUCT_NAME=$(echo "$DEV_INFO" | grep "iProduct" | head -1 | sed -E 's/.*<([^>]+)>.*/\1/')

        if [ -n "$MANUFACTURER" ] && [ -n "$PRODUCT_NAME" ]; then
            DEVICE_NAME="$MANUFACTURER $PRODUCT_NAME"
        else
            DEVICE_NAME="USB-устройство"
        fi
        STATUS="unknown"
    fi

    # Проверяем, существует ли запись
    EXISTS=$(sqlite3 "$REGISTRY_FILE" "SELECT 1 FROM devices WHERE bus='usb' AND vendor='$VENDOR' AND device='$PRODUCT';" 2>/dev/null)

    if [ -z "$EXISTS" ]; then
        sqlite3 "$REGISTRY_FILE" <<EOF
INSERT INTO devices (bus, vendor, device, name, status, driver, detected_at)
VALUES ('usb', '$VENDOR', '$PRODUCT', '$DEVICE_NAME', '$STATUS', '', CURRENT_TIMESTAMP);
EOF
        echo "  USB: $VENDOR:$PRODUCT -> $DEVICE_NAME (статус: $STATUS) [НОВОЕ]"
    else
        sqlite3 "$REGISTRY_FILE" <<EOF
UPDATE devices SET name='$DEVICE_NAME', status='$STATUS', detected_at=CURRENT_TIMESTAMP
WHERE bus='usb' AND vendor='$VENDOR' AND device='$PRODUCT';
EOF
        echo "  USB: $VENDOR:$PRODUCT -> $DEVICE_NAME (статус: $STATUS) [ОБНОВЛЕНО]"
    fi
done

# -------------------------------------------------------------------
# 3. Удаление отсутствующих устройств
# -------------------------------------------------------------------
echo "Проверка отсутствующих устройств..."

sqlite3 "$REGISTRY_FILE" "SELECT bus, vendor, device FROM devices;" 2>/dev/null | while IFS='|' read -r bus vendor device; do
    if [ -z "$bus" ] || [ -z "$vendor" ] || [ -z "$device" ]; then
        continue
    fi

    if ! grep -q "^${bus}|${vendor}|${device}$" "$DETECTED_DEVICES" 2>/dev/null; then
        DEVICE_NAME=$(sqlite3 "$REGISTRY_FILE" "SELECT name FROM devices
                       WHERE bus='$bus' AND vendor='$vendor' AND device='$device';" 2>/dev/null)
        echo "  Удаление: $bus $vendor:$device ($DEVICE_NAME)"
        log_to_registry "info" "Устройство удалено: $bus $vendor:$device"
        sqlite3 "$REGISTRY_FILE" "DELETE FROM devices
                                  WHERE bus='$bus' AND vendor='$vendor' AND device='$device';" 2>/dev/null
    fi
done

rm -f "$DETECTED_DEVICES"
log_to_registry "info" "Проверка устройств завершена"
echo "Проверка устройств завершена."
