#!/bin/bash

DISK=$(isoinfo -d -i /dev/sr0 | grep "Volume id" | cut -c 12- ) 

# Проверяем, не пустая ли переменная
if [ -z "$DISK" ]; then
    echo "Ошибка: Диск в /dev/sr0 не найден или не читается."
    sleep 15
    exit 1
fi
mountpoint -q /media/cdrom || { echo "Не смонтирован"; sleep 15; exit 1; }

FILE_NAME="/home/brusee/Документы/0/files_tree_$DISK.json"
TMP_FILE="/home/brusee/Документы/0/.files_tree_tmp_md5_$DISK.json"

cd /media/cdrom0 || exit 1
FULL_TREE_JSON=$(tree -axNsDfJ --inodes --sort=name)

if [ -f "$FILE_NAME" ]; then
 
    # Сохраняем точное время доступа (atime) и изменения (mtime) оригинала
    # Используем формат %x и %y для максимальной точности
    ATIME=$(stat -c "%x" "$FILE_NAME")
    MTIME=$(stat -c "%y" "$FILE_NAME")

    # Копируем файл с сохранением атрибутов (-p сохранит mtime у .old)
    cp -p "$FILE_NAME" "$FILE_NAME.old" 
else
    printf "%s\n" "$FULL_TREE_JSON" >  $FILE_NAME
    jq  --arg DISK "$DISK"  '.[0]["name"] = $DISK' "$FILE_NAME" > /tmp/files_tree_tmp.$DISK && mv /tmp/files_tree_tmp.$DISK "$FILE_NAME"
fi

# Извлекаем все уникальные пути "name" из объектов, где "type": "file" (рекурсивно по всему дереву из файла и с диска)
mapfile -t COMBINED_UNIQUE < <(
    {
        # Источник 1: вывод tree (убрали -o, чтобы шел в stdout)
        echo "$FULL_TREE_JSON" | jq -r '.. | objects | select(.type == "file") | .name'
        
        # Источник 2: ваш текущий массив (из файла)
        jq -r '.. | objects | select(.type == "file") | .name' "$FILE_NAME"
    } | sort -u
)

# Копируем файл для работы
cp "$FILE_NAME" "$TMP_FILE"

# Проходим циклом по найденным путям
for filepath in "${COMBINED_UNIQUE[@]}"; do
    if [ -f "$filepath" ]; then
        CURRENT_MD5=$(md5sum "$filepath" | awk '{print $1}')

        # Извлекаем существующий MD5 для этого конкретного пути (первый найденный)
        EXISTING_MD5=$(jq -r --arg name "$filepath" '.. | objects | select(.type == "file" and .name == $name) | .md5 // empty' "$FILE_NAME" | head -n 1)
        FOUND_NAME=$(jq -r --arg name "$filepath" '.. | objects | select(.type == "file" and .name == $name) | .name' "$FILE_NAME" | head -n 1)
        if [ -n "$EXISTING_MD5" ] && [ "$EXISTING_MD5" != "null" ]; then
            if [ "$CURRENT_MD5" = "$EXISTING_MD5" ]; then
                echo "OK: $filepath"
            else
                echo "CHANGED: $filepath (был $EXISTING_MD5, стал $CURRENT_MD5)"
                # Обновляем значение md5 рекурсивно по всему дереву
                # walk(if type == "object" ...) проходит через каждый объект в JSON
                jq --arg name "$filepath" --arg md5 "$CURRENT_MD5" \
                  'walk(if type == "object" and .type == "file" and .name == $name then .md5 = $md5 else . end)' \
                  "$TMP_FILE" > "${TMP_FILE}.new" && mv "${TMP_FILE}.new" "$TMP_FILE"
            fi
        elif [[ ( -z "$EXISTING_MD5"  ||  "$EXISTING_MD5" == "null" ) && ( -n "$FOUND_NAME"  &&  "$FOUND_NAME" != "null" ) ]]; then
                echo "CHANGED: $filepath (хеш $CURRENT_MD5)"
                # Обновляем значение md5 рекурсивно по всему дереву
                # walk(if type == "object" ...) проходит через каждый объект в JSON
                jq --arg name "$filepath" --arg md5 "$CURRENT_MD5" \
                  'walk(if type == "object" and .type == "file" and .name == $name then .md5 = $md5 else . end)' \
                  "$TMP_FILE" > "${TMP_FILE}.new" && mv "${TMP_FILE}.new" "$TMP_FILE"
        else
            echo "NEW/EMPTY: $filepath (хеш $CURRENT_MD5)"
             
            # Извлекаем из вывода tree полный объект этого файла (со всеми метаданными)
            # Мы используем -f в tree для сопоставления по полному пути
           TREE_OBJ=$(printf "%s\n" "${FULL_TREE_JSON[@]}" | jq -c --arg name "$filepath" '[.[] | .. | objects] | map(select(.type == "file" and .name == $name)) | .[0]')

           # 2. Если объект в tree найден, вставляем его в JSON
            if [ -n "$TREE_OBJ" ] && [ "$TREE_OBJ" != "null" ]; then

                # Определяем имя родителя
                PARENT_PATH=$(dirname "$filepath")
                CLEAN_PATH=$(echo "$PARENT_PATH" | sed 's|^/*||;s|/*$||')
                IFS='/' read -ra ADDR <<< "$CLEAN_PATH"
                CURRENT_CHECK_PATH=""

                # Формируем отсутствующую ветку
                for i in "${!ADDR[@]}"; do
                    part="${ADDR[$i]}"
                    if [ -z "$CURRENT_CHECK_PATH" ]; then
                        # Для первой итерации (корень)
                        CURRENT_CHECK_PATH="$DISK"
                        PARENT_FOR_WALK=""
                        # Путь для поиска в доноре (обычно корень там это имя диска или ".")
                        LOOKUP_PATH="$DISK"
                    else
                        # Для подпапок
                        PARENT_FOR_WALK="$CURRENT_CHECK_PATH"
                        CURRENT_CHECK_PATH="${CURRENT_CHECK_PATH}/$part"

                        # Формируем относительный путь для поиска в доноре (./part1/part2)
                        if [ "$i" -eq 1 ]; then
                            LOOKUP_PATH="./$part"
                        else
                            LOOKUP_PATH="${LOOKUP_PATH}/$part"
                        fi
                    fi

                    # Проверка существования (защищенная) CURRENT_CHECK_PATH=[$CURRENT_CHECK_PATH]
                    EXISTS=$(jq --arg path "$LOOKUP_PATH" \
                      '.. | objects? | select(.name == $path) | any' "$TMP_FILE" 2>/dev/null)
                    if [[ "$EXISTS" != "true" ]]; then
                        if [ "$i" -eq 0 ]; then

                            # КОРЕНЬ: Извлекаем ПЕРВЫЙ ОБЪЕКТ из массива донора
                            BRANCH=$(printf "%s\n" "${FULL_TREE_JSON[@]}" | jq -c --arg name "$LOOKUP_PATH" '[.[] | .. | objects] | map(select(.type == "directory" and .name == $name)) | .[0]')
                        else
                            # ПОДПАПКА: Ищем в массиве донора объект по его пути
                            BRANCH=$(printf "%s\n" "${FULL_TREE_JSON[@]}" | jq -c --arg name "$LOOKUP_PATH" '[.[] | .. | objects] | map(select(.type == "directory" and .name == $name)) | .[0] | .contents = []')
                        fi
                        if [ -n "$BRANCH" ] && [ "$BRANCH" != "null" ]; then
                            if [ "$i" -eq 0 ]; then
                                # Создаем файл как ОБЪЕКТ
                                echo "$BRANCH" > "$TMP_FILE"
                            else
                                # Вставка в родителя через walk (теперь TMP_FILE точно объект)
                                jq --arg p_path "$PARENT_FOR_WALK" --argjson b "$BRANCH" \
                                    'walk(
                                        if type == "object" and .name == $p_path then
                                            if (.contents | map(select(.name == $b.name)) | length == 0) then
                                                .contents += [$b]
                                            else . end
                                        else . end
                                    )' "$TMP_FILE" > "${TMP_FILE}.tmp" && mv "${TMP_FILE}.tmp" "$TMP_FILE"
                            fi
                        fi
                    fi
                done

                # 3. Теперь, когда ветка точно есть, вставляем сам файл
                jq --arg p_path "$PARENT_PATH" \
                   --argjson newObj "$TREE_OBJ" \
                   --arg md5 "$CURRENT_MD5" \
                   'walk(
                      if type == "object" and .type == "directory" and .name == $p_path then
                        # Проверяем, нет ли уже там такого файла, чтобы не дублировать
                        if (.contents | map(select(.name == $newObj.name)) | length == 0) then
                          .contents += [$newObj | .md5 = $md5]
                        else . end
                      else . end
                   )' "$TMP_FILE" > "${TMP_FILE}.new" && mv "${TMP_FILE}.new" "$TMP_FILE"
            fi
        fi

    fi
done

# рекурсивно сортируем ВСЕ объекты, где есть .contents
jq '
walk(
    if type == "object" and .contents then
        .contents |= sort_by(.name, .inode)
    else . end
)' "$TMP_FILE" > "${TMP_FILE}.tmp" && mv "${TMP_FILE}.tmp" "$TMP_FILE"

# Проверяем, есть ли отличия между файлами
if cmp -s "$FILE_NAME" "$TMP_FILE"; then
    echo "Изменений не обнаружено."
    rm "$TMP_FILE"
else
    echo -e "\nОБНАРУЖЕНЫ ИЗМЕНЕНИЯ!"
    echo "1) Перезаписать исходный файл ($FILE_NAME)"
    echo "2) Сохранить как новый файл (по умолчанию ${FILE_NAME%.json}_new.json)"
    echo "3) Отмена"
    read -p "Выберите вариант (1-3): " choice

    case $choice in
        1)
            mv "$TMP_FILE" "$FILE_NAME"
            echo "Файл обновлен."
            exit 0
            ;;
        2)                
             # Формируем имя по умолчанию
             DEFAULT_NAME="${FILE_NAME%.json}_new.json"
             # Флаг -e включает readline, а -i подставляет текст прямо в строку ввода
             read -e -p "Имя нового файла: " -i "$DEFAULT_NAME" NEW_NAME
             mv "$TMP_FILE" "$NEW_NAME"
             echo "Сохранено в файл: $NEW_NAME"
            ;;
        3)
            echo "Отменено. Временный файл удален."
            rm "$TMP_FILE"
            ;;
        *)
            echo "Неверный выбор. Временный файл удален. Выход."
            rm "$TMP_FILE"
            ;;
    esac
fi


if [ -f "$FILE_NAME.old" ]; then
    # Принудительно возвращаем время ДОСТУПА и ИЗМЕНЕНИЯ оригиналу
    # (так как чтение обновило его atime)
    touch -a -d "$ATIME" "$FILE_NAME"
    touch -m -d "$MTIME" "$FILE_NAME"
fi

if [ -f "$FILE_NAME.old" ]; then
    echo -e "\nСоздана копия старого файла: $FILE_NAME.old"
    read -p "Удалить ее? (y/n) [по умолчанию: y]: " rm_choice
    rm_choice=${rm_choice:-y}
    if [[ "$rm_choice" =~ ^[YyДд]$ ]]; then
        rm "$FILE_NAME.old"
        echo "файл $FILE_NAME.old удален."
    else
        echo "файл $FILE_NAME.old сохранен"
    fi
fi
