#!/bin/bash
#160219 ander
#260131 sfs
#which sudoq && sudoq=sudoq || sudoq=sudo
[ "`whoami`" != "root" ] && { pkexec ${0} "${@}" ; exit ; } || { export XDG_RUNTIME_DIR=/run/user/$(loginctl list-sessions --no-legend | awk '$4 ~ /seat[0-9]+/ && ! /root/ {print $2}' | sort -u) ; PATH="$PATH":/usr/local/bin ; }
yad --version |grep -E '^0' && gtk=gtk || gtk=yad
ping -c 2 -W 3 8.8.8.8 >/dev/null || exit 1
value() { egrep -o "(^| )$1=[^ ]+" /proc/cmdline | cut -d= -f2; } ; export -f value
#sysdir=$(dirname $(realpath "/mnt/home/`value dir`/modules"))
#sysdir="$(realpath "/mnt/home/`value dir`/")"
sysdir="/mnt/home/`value dir`"
tmpdir="/tmp/mod_update" ; export tmpdir  # экспорт - для работы справки
export blacklistfile="$sysdir"/modules/mod-up.blacklist  # если новый модуль присутствует в этом списке - будет игнорироваться

pkill -f "yad --text=Обновление модулей.pfs"
# splitname <разбираемое имя файла> <переменная под имя> <переменная под версию>
# пример: splitname $pfsname modname modver
splitname(){
  local ver sver
  ver=$(echo "$1" \
        |sed 's/i[3-6]86\|x86[_-]64\|x64\|[Xx][Ff][_-]\?86\|[Qq][Tt]4/masq/g
              s/_64/_masq/g' \
        |grep -oE '[_-]([A-Za-z]{0,2}[0-9][a-z0-9]*[_.+-])+')
  local re1='\(.*\)' re2='\1' n=1 partver
  for partver in $ver ; do
     n=$(($n+1))
     partver=${partver%?}
     partver=${partver#?}
     re1="${re1}$partver\\(.*\\)"
     re2="${re2}.*\\$n"
     sver="${sver}${sver:+-}$partver"
  done
  declare -g $2=$(echo "$1" |sed 's/'$re1'\.pfs/'$re2'\\.pfs/')
  declare -g $3=$sver
}

# newer <версия1> <версия2> - версия1 больше/новее версии2 ?
newer(){ [ "$1" != "$2" -a $(echo -e "$1\n$2"|sort -V|tail -1) == "$1" ] ; }

HELP(){
ntf -w "Обновление модулей.pfs из интернет репозитория." \
"
Свежий модуль будет загружены в директорию с устаревшим модулем.
Устаревший модуль переименовывается в *.old.

Если эта директория недоступна для записи - загруженные свежие модули останутся в $tmpdir
Перенесите их вручную.

Чтобы изменения вступили в силу - перезагрузите систему.

Если Вы не хотите видеть предложение обновить именно на эту конкретную версию,\
 отметьте ее в колонке ЧС  для занесения в черный список (находится в modules/mod-up.blacklist).
 
 Ключи запуска:
 -b выполнить в фоне
 -f принудительно обновить список модулей" >/dev/null
}; export -f HELP

# START
unset background
[ "`echo "$@" |grep "\-b"`" ] && export background="yes"  # export - для getrepolist
[ "`echo "$@" |grep "\--help"`" ] && { HELP; exit ; }
[ "`echo "$@" |grep "\-f"`" ] && f="-f"

[ -d "$tmpdir" ] || mkdir -p -m 777 "$tmpdir"
cd "$tmpdir"
rm -f *.html newmodfound 2>/dev/null
[ "$(ls *.html newmodfound 2>/dev/null)" ] &&
         { echo "Не могу удалить временные файлы в $tmpdir"; exit 1; }

getrepolist $f || exit 1  # не удалось скачать список файлов в репозитории

unset newmod reportmess
num=0

emod="`value extramod`"
if [ "`echo "$emod" |grep -E '^/'`" ]; then
     extdir="$(realpath "$emod")"
else [ "$emod" ] && extdir="$(realpath "/mnt/home/$emod")"
fi
#aufs="`mount |grep "on / type aufs"`"

xxP1(){
for i in `find "$sysdir/base" "$sysdir/modules" "$sysdir/optional" "$extdir"  -mindepth 2 -type f -name *.pfs` ; do basename $i ;done 
[ "$aufs" ] && cat $( ls -1 /sys/fs/aufs/*/br[0-9]* ) \
   | sed -n 's|^.*/\.\?\(.*\.pfs\)=r.*$|\1|p' 
}
P(){
#find "$sysdir/base" "$sysdir/modules" "$sysdir/optional"  "$extdir"  -mindepth 2 -type f -name *.pfs
find "$sysdir/base" "$sysdir/modules" "$sysdir/optional"  "$extdir"  -type f -name *.pfs -exec realpath {} \;
#find "$sysdir" "$sysdir/modules" "$sysdir/optional"  "$extdir"  -mindepth 2 -type f -name *.pfs
losetup -O BACK-FILE | grep -E '.pfs$'
}
#P ;exit
P |sort -u | while read pfsname ; do 
#	losetup -a |grep "$pfsname" |grep "($sysdir" >/dev/null  || continue #Модуль в папке дистриба
        pfsname1="`basename "$pfsname"`"
        splitname $pfsname1 modname modver
        for similarpfs in $(grep "$modname" repolist.txt |grep -v "$pfsname1" |cut -d' ' -f1); do
           splitname $(basename "$similarpfs") rname rver
           [ "$modname" == "$rname" ] \
           && newer "$rver" "$modver" \
           && ! grep -q "$(basename "$similarpfs")" "$blacklistfile" 2>/dev/null \
           && { modver="$rver"   # берем, если имя пакета то же, версия новее и данный файл не в ЧС
                newmod="$similarpfs"
                newmod_basename=$(basename "$newmod")
              }
        done
        [ "$newmod" ] && {
           # если модуль есть в нескольких репозиториях - возьмем из первого по списку
           newmod=$(grep -m 1 "$newmod_basename" repolist.txt |cut -d' ' -f1)
           # а размер возьмем тот, который не '?M'
           newmod_size=$(grep "$newmod_basename" repolist.txt |cut -d' ' -f3 \
                         |grep -v '\?M$'|head -n 1)
           [ "$newmod_size" ] || newmod_size="-"
           echo "false"
           echo "false"
           echo "$pfsname1"
           echo "$newmod_basename"
           echo "$newmod"
           echo "$newmod_size"
           newmod=""
           echo "$pfsname"
        }
        num=$(($num+1))
        echo "#Проверено $num" >&2
     done 2>&1 >newmodfound \
  |if [ ! "$background" ] ; then
      yad --progress --pulsate --center --image="gtk-refresh" --name="gtk-refresh" \
          --no-buttons --text="<b>Идет поиск обновлений...</b>" \
          --auto-close --borders=15 --undecorated --skip-taskbar
   else
      # wt -start "Поиск обновленных модулей"
      cat >/dev/null
      # wt -kill
   fi
#export dir="$(realpath "/mnt/home/`value dir`/")"
CHK(){ [ ! -f "$blacklistfile" ] && ntf -a "$blacklistfile " "не существует" && exit ;} ; export -f CHK
#F(){ CHK ; cat $(find  "$sysdir" -maxdepth 2 -type f -name mod-up.blacklist) |leafpad ;} ; export -f F
F(){ CHK ; leafpad "$blacklistfile" ;} ; export -f F
#D(){ CHK ; wt "sudoq rm $(find  "$dir" -maxdepth 2 -type f -name mod-up.blacklist)"  ;} ; export -f D
D(){ CHK ; wt "$sudoq rm $blacklistfile" ;} ; export -f D

if [ -s newmodfound ] ; then

#UPY(){
        ya="`cat newmodfound | yad --title "Обновление модулей.pfs" \
                  --height=340 --width=760 --center \
                  --text "Выберите модули для обновления\nСтарые модули будут переименованы в *.old\nЧС - черный список" \
		  --window-icon="gtk-refresh" \
		  --image="gtk-refresh" --name="gtk-refresh" --image-on-top \
                  --list --checklist \
                  --Xseparator="\n" \
                  --column="Upd!Отметить для обновления":CHK \
                  --column="в ЧС!Отметить для добавления в Черный Список (далее не будет обновляться)":CHK \
                  --column="В наличии!В директории дистрибутива или загружен из другого места" \
                  --column="В репозитории!Обновленный модуль.pfs в интернет репозитории" \
                  --column="URL" \
                  --column="Mb!Размер модуля в репозитории" \
                  --Xcolumn="В наличии (PATH)":HD \
                  --column="В наличии (PATH)" \
                  --hide-column=5 \
                  --expand-column=4 \
                  --print-column=0 \
                  --print-all \
                  --button=Помощь!gtk-help:"/bin/sh -c HELP" \
                  --button=ЧС!gtk-file!"Просмотреть ЧС":"/bin/sh -c F" \
                  --Xbutton="<s>ЧС</s>"!gtk-delete!"Удалить Черный Список":"/bin/sh -c D" \
                  --button="<s>ЧС</s>"!gtk-delete!"Удалить Черный Список":3 \
                  --button="Выполнить"\!gtk-refresh\!"Выбранные обновления будут загружены или модуль будет занесен в ЧС":0 \
                  --button=$gtk-cancel:1 
`"
#}
#export -f UPY
#UPY #;exit
#echo "$ya" ;exit
# === ПОЛУЧАЕМ ВЫБОР ПОЛЬЗОВАТЕЛЯ В ПЕРЕМЕННУЮ ===
#user_choice=$(UPY)
yad_exit_code=$?
#echo $yad_exit_code ; exit
[ $yad_exit_code -eq 3 ] && D && mod-up &
#[ $yad_exit_code -eq 3 ] && D && `realpath "$0"` &

if [ $yad_exit_code -ne 0 ]; then
    # Пользователь отменил → выходим
    rm -f newmodfound
    exit 0
fi

# === ОБРАБАТЫВАЕМ ВЫБОР ПОЛЬЗОВАТЕЛЯ ЧЕРЕЗ HERE-STRING (БЕЗ ПОДОБОЛОЧКИ) ===
#while read -r checked &&
#      read -r oldmod &&
#      read -r newmod &&
#      read -r newmod_url &&
#      read -r newmod_size &&
#      read -r to_blacklist
#do
for j in `echo "$ya|"` ;do
    newmod="` echo "$j" |awk -F"|" '{print $4}'`"
    to_blacklist="` echo "$j" |awk -F"|" '{print $2}'`"
    if [ "$to_blacklist" = "TRUE" ]; then
	[ -w "$blacklistfile" ] && sudo= || sudo=$sudoq
        $sudo echo "$newmod" >>"$blacklistfile"
#        $sudo wt "echo $newmod >> $blacklistfile"
        continue
    fi
    checked="`echo "$j" |awk -F"|" '{print $1}'`"
    #ntf -a "$checked $newmod"
    [ "$checked" = "FALSE" ] && continue
    oldmod="` echo "$j" |awk -F"|" '{print $3}'`"
    newmod="` echo "$j" |awk -F"|" '{print $4}'`"
    newmod_url="` echo "$j" |awk -F"|" '{print $5}'`"
    newmod_size="` echo "$j" |awk -F"|" '{print $6}'`"
    oldmod_fp="` echo "$j" |awk -F"|" '{print $7}'`"

    oldmod_dir="$(dirname "$oldmod_fp")"
    foundinlocaldir="$oldmod_dir/$newmod"
##    foundinlocaldir=$(for i in $(find "$sysdir" -mindepth 2 -type f -name "$newmod"); do dirname "$i"; done)
#    foundinlocaldir="$(find "$sysdir" -mindepth 2 -type f -name "$newmod")"
#    if [ -n "$foundinlocaldir" ]; then
    if [ -f "$foundinlocaldir" ]; then
        msg1="уже есть в\n $foundinlocaldir"
        msg="Можете его подключить"
        for i in $foundinlocaldir; do
            echo "$i" | grep -qE '/base|/modules' && {
                [ -e "$i/$oldmod" ] && mv "$i/$oldmod" "$i/${oldmod}.old"
                msg="Перегрузите систему для подключения"
            }
        done
        ntf -w "$newmod " "$msg1\n$msg "
        continue
    fi
X2(){
    wget -c --progress=dot "${newmod_url}" 2>&1 \
    | sed -nu '/%/s/^.* \+\([0-9]\+%\).*$/\1/p; /%/s/^/#/p' \
    | yad --progress --title="Загрузка $newmod" --text "Загрузка $newmod" \
          --height=50 --Xwidth=350 --center \
          --window-icon="gtk-refresh" --image="gtk-refresh" --name="gtk-refresh" \
          --auto-close --auto-kill
}
    wget-progress3 $tmpdir "$newmod" "$newmod_url" 
    wget_status="${PIPESTATUS[0]}"
    if [ $wget_status -gt 0 ]; then
        echo "Сбой загрузки. $newmod загрузить не удалось"
        rm -f "$newmod" 2>/dev/null
        continue
    fi

    datetime=$(date)
    copied=""
#    for oldmod_fp in $(find "$sysdir" -mindepth 2 -type f -name "$oldmod"); do
#	oldmod_fp="$(losetup |awk '/'$oldmod'/ {print $6}')"
	[ -w "$oldmod_dir" ] && sudo= || sudo=$sudoq
        warn=w
        if $sudo cp "$newmod" "$oldmod_dir"; then
            copied="yes"
            echo "$newmod ==> $oldmod_dir"
            reportmess="$reportmess\n$newmod ==> $oldmod_dir"
            echo "$datetime" >>"${oldmod_dir}/update.log"
            echo "$newmod added" >>"${oldmod_dir}/update.log"
            if $sudo mv "$oldmod_fp" "${oldmod_fp}.old"; then
                echo -e "${oldmod_dir}\n${oldmod} ==> ${oldmod}.old"
                reportmess="$reportmess\n<s>${oldmod_dir}/${oldmod}</s>"
                echo "${oldmod} ==> ${oldmod}.old" >>"${oldmod_dir}/update.log"
            else
                echo "$newmod не удалось переименовать старый файл в ${oldmod_dir}"
                warn=a
            fi
        else
            echo "$newmod не удалось перенести в ${oldmod_dir}"
            warn=a
        fi
#    done
    [ -n "$copied" ] && rm -f "$newmod"
done

# === ФИНАЛЬНЫЙ ОТЧЁТ ===
rm -f newmodfound
files=$(ls -1 -I repolist.txt 2>/dev/null)
warn=w
if [ -n "$files" ]; then
    reportmess="Обновлены модули:\n$files\nПеренесите их вручную из $tmpdir"
    reportmess="$reportmess\nМодули загружены, но не перенесены в директорию с файлами системы."
    warn=a
fi

if [ ! -f /tmp/mod-up-err ]; then
    if [ -n "$reportmess" ]; then
        m1="\nЧтобы изменения вступили в силу для базовых ($sysdir/base) модулей - перезагрузите систему."
        m1="$m1\nЕсли обновился модуль, подключенный вручную, переподключите его."
        ntf -$warn "Отчет обновления модулей.pfs" "<small>$reportmess</small>\n$m1"
    fi
fi

else
    [ "$background" ] && n=i || n=w
    ntf -$n "Поиск в интернет репозитории обновленных"$'\n'"версий модулей.pfs." \
            "Обновлений не найдено."
    exit 0
fi
