#!/bin/bash

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# Tool for generating various logs and save into a file.
#
# NOTE: Even though effort has been made for removing personal information,
#       logs may still contain some personal information.
#       Thus the user may create an additional filter for removing
#       personal data from the logs.
#       See the end of function "RemovePersonalData"
#       and file "$DIR_OF_CONFIG/manjaro-help-filter.sh" below.
#
# Forked from EndeavourOS: Author: manuel-192

# edited line ~101 by cscs

PARTITION=""
expire=90

mlh_yad() {
    local icon=/usr/share/icons/manjaro/maia/maia.svg
    local window_icon=/usr/share/icons/manjaro/maia/32x32.png

    if [ -r "$icon" ] ; then
        GDK_BACKEND=x11 /usr/bin/yad --center --window-icon="$icon" --image="$window_icon" --title="Manjaro Log Helper  ${PARTITION}" "$@"
    else
        GDK_BACKEND=x11 /usr/bin/yad --center --title="Manjaro log tools ${PARTITION}" "$@"
    fi
}

Msg() {
    local msg="$1"
    local title="$2"
    shift 2
    local width=$((${#msg} * 10))
    local highlimit=650
    local lowlimit=200

    test $width -gt $highlimit && width=$highlimit
    test $width -lt $lowlimit  && width=$lowlimit

    echo "$msg" | mlh_yad --text-info --title="$title" --formatted --wrap \
                          --width=$width --height=100 --button="Open":1 --button=yad-quit "$@"
}
ErrorMsg() {
    local msg="$1"
    Msg "$msg" "Error"
}
WarningMsg() {
    local msg="$1"
    Msg "$msg" "Warning"
}

Header() { printf "%s\n\n" "#################### $* ########################" ; }
Footer() { printf "\n\n" ; }

Cmd() {
    local cmd="$1"

    if [ "$cmd" = "cat" ] ; then
        if [ "${2::1}" = "." ] ; then
            cd                  # $HOME stuff: go to $HOME to hide unnecessary info
        fi
    fi

    case "$cmd" in
        pkexec)
            shift
            SUDO_CMDS+=" ; echo '$(Header "$@")' >> $FILE_OF_LOGS"
            if [[ "$1" == "journalctl" && -n "$PARTITION" ]]; then
                SUDO_CMDS="mount ${PARTITION} /mnt/ --read-only; ${SUDO_CMDS}; $* --no-pager -D /mnt/var/log/journal >> $FILE_OF_LOGS; umount /mnt"
            else
                SUDO_CMDS+=" ; $* >> $FILE_OF_LOGS"
            fi
            SUDO_CMDS+=" ; echo '$(Footer)' >> $FILE_OF_LOGS"
            return
            ;;
    esac

    Header "$@" >> "$FILE_OF_LOGS"
    if [ -n "$cmd" ] && [ -x /usr/bin/"$cmd" ] ; then
        "$@" >> "$FILE_OF_LOGS"
    else
        WarningMsg "Command '$cmd' not found."
        echo "Sorry, command '$cmd' not found." >> "$FILE_OF_LOGS"
    fi
    Footer >> "$FILE_OF_LOGS"
}

SendToInternet() {

    RemovePersonalData  # always before sending logs to the internet

#    local url=$(wgetpaste -e $expire -s dpaste $FILE_OF_LOGS)
    local url=$( cat $FILE_OF_LOGS | curl -s -F "expiry_days="$expire"" -F "content=<-" https://dpaste.com/api/v2/)
    echo -e "\n\n-------------------------\ndpaste.com:\t ${url}"

    echo "$(date '+%Y-%m-%d %H:%M:%s'): $url" >> "$DIR_OF_CONFIG"/url-list.txt

    mlh_yad --text="$url\n<i>Note: this link will be deleted after $expire days</i>\n" --button="Copy":0 --button="Open":2 --button="Open in a text editor":3 --title="Result URL" --width=300
    local opt=$?
    case $opt in
        0) if [[ "DESKTOP_SESSION" =~ "plasma" ]]; then
                qdbus org.kde.klipper /klipper setClipboardContents "$url"
            elif [[ -x /usr/bin/xclip ]]; then
                echo "$url" | xclip -i -selection clipboard
            #TODO
            #if wayland ???
            fi ;;
        2) xdg-open $url ;;
        3) xdg-open $FILE_OF_LOGS
    esac
    isSendToInternet=${#url}
}

UserNames() {
    local low="$1"     # lowest  user id number
    local high="$2"    # highest user id number
    local nr
    local user users=""

    for nr in $(cat /etc/passwd | cut -d ':' -f 3) ; do
        if [ $nr -ge $low ] && [ $nr -le $high ] ; then
            user=$(grep ":$nr:" /etc/passwd | cut -d ':' -f 1)
            if [ -z "$users" ] ; then
                users="$user"
            else
                users+=" $user"
            fi
        fi
    done
    echo "$users"
}

RemovePersonalData() {
    if [ ! -r "$FILE_OF_LOGS" ] ; then
        ErrorMsg "No logs!"
        exit 1
    fi
    cp -a "$FILE_OF_LOGS" "$FILE_OF_LOGS.bak"

    # hide real user names (that are found in /etc/passwd) from logs
    for user in $(UserNames 1000 50000) ; do
        sed -i "$FILE_OF_LOGS" \
            -e 's| '$user' | _user_ |g' \
            -e 's|/'$user'/|/_user_/|g' \
            -e 's|"'$user'"|"_user_"|g' \
            -e 's|'$user:$user'|_user_:_user_|g' \
            -e 's|/'$user'|/_user_|g' \
            -e 's| '$user'$| _user_|g' \
            -e 's| '$user':| _user_:|g' \
            -e "s|'"$user"'|'_user_'|g" \
            -e 's| '$user'\.| _user_.|g' \
            -e 's|:'$user' |:_user_ |g' \
            -e 's|:'$user')|:_user_)|g' \
            -e 's| '$user')| _user_)|g' \
            -e 's| '$user'(| _user_(|g' \
            -e "s|‘$user:|‘_user_:|g" \
            -e "s|\[$user\]|[_user_]|g" \
            -e 's|'$user'"|_user_"|g'
    done

    # hide hostname from logs
    sed -i "$FILE_OF_LOGS" \
        -e 's| '$HOSTNAME' | _hostname_ |g' \
        -e 's|"'$HOSTNAME'"|"_hostname_"|g' \
        -e 's|<'$HOSTNAME'>|<_hostname_>|g' \
        -e 's|='$HOSTNAME' |=_hostname_ |g' \
        -e 's| '$HOSTNAME'\.| _hostname_.|g' \
        -e 's| '$HOSTNAME'"| _hostname_"|g' \
        -e 's|-'$HOSTNAME':|-_hostname_:|g' \
        -e "s|'"$HOSTNAME"'|'_hostname_'|g"

    # User may create an additional filter for removing
    # any remaining personal data from the logs.
    local filter="$DIR_OF_CONFIG"/manjaro-help-filter.sh
    if [ -r "$filter" ] ; then
        # $filter refers to user's own bash script
        # $FILE_OF_LOGS is the file containing all gathered logs
        bash "$filter" "$FILE_OF_LOGS"
    fi
    removePersonalInfo=yes
}

get_Manjaro_Partitions(){
    #test by sudo ./mlh -getparts
    mountdir="/tmp/mnt-"
    mkdir "${mountdir}"
    declare -a manjaros=()
    while read -r partition label; do
        #echo -e "\n:: ${partition} (${label})??"
        if mount  "${partition}" "${mountdir}" --read-only >/dev/null; then # -o sync
            if [[ -d "${mountdir}/etc" && -f "${mountdir}/etc/lsb-release" ]]; then
                if [[ $(grep -c -i 'Manjaro' ${mountdir}/etc/lsb-release) > 0 ]]; then
                    echo -e "false ${partition}\t${label}"
                fi
            fi
            umount "${mountdir}" >/dev/null
        fi
    done < <(lsblk -lfn -o "FSTYPE,PATH,TYPE,PTTYPE,PARTTYPE,LABEL" | awk '/ 0x83 / {print $2" "$6}')
    rmdir "${mountdir}"
}

Welcome()
{   mlh_yad --text-align=center --text="\n\n<b>Welcome to Manjaro Log Helper</b>\nObtain error logs from your system.\n\nPress <b>OK</b> to continue or <b>Cancel</b> to exit."

    [[ $? -eq 0 ]] || exit 1
}

Main()
{
    local FILE_OF_LOGS=$HOME/manjaro-log-helper.logs
    local DIR_OF_CONFIG="$HOME/.config/manjaro-log-helper"
    local SUDO_CMDS=":"
    #EXPORT SYSTEMD_COLOR=false # no color codes in logs

    #TODO id user == manjaro or if is in iso ?
    if [[ "$USER" == "manjaro" ]]; then
        #TODO change path /usr/bin for run after install
        local partitions=$(pkexec "${PWD}/mlh" -getparts)
        local result=$(
            mlh_yad --list --radiolist --width=750 --height=655 --text="Select your Manjaro partition" \
            --no-click \
            --column="Select" --column="Partition" --column="Label" \
            $partitions
        )
        PARTITION=$(echo "$result" | awk -F'|' '{print $2}')
    fi

    mkdir -p "$DIR_OF_CONFIG"

    rm -f "$FILE_OF_LOGS"

    echo "Generated on $(date '+%Y-%m-%d %H:%M:%s')" > $FILE_OF_LOGS
    echo "" >> $FILE_OF_LOGS

    local rdtip="Rename personal names to generic names"
    local sltip="Send gathered logs to the internet (personal info always removed)"

    local journal0="journalctl -b 0"
    local journal1="journalctl -b -1"
    local journal2="journalctl -b -2"
    local install="Manjaro install log"
    local blame="systemd-analyze blame"
    local lspci="lspci -vnn"
    local lspcit="lspci -vt"
    local lsusb="lsusb -vt"
    local inxi="inxi -Fxzc0"
    local rdbut="<i>Remove personal data from logs</i>"
    local slbut="<i>Send logs to dpaste pastebin service</i>"
    local save="Save this log"

    local cmds
    local isSendToInternet=0
    local removePersonalInfo="no"
    local xx
    local helptext=""

    helptext+="Selecting any of the boxes below (except the last two)\n"
    helptext+="will add that particular log to a common log file: (<b>$FILE_OF_LOGS</b>).\n"
    helptext+="Once you have selected the desired boxes, including '$slbut',\n"
    helptext+="click the OK button to generate a URL.\n\n"
    helptext+="Note1: Your personal data will be automatically removed from logs before sending to pastebin service.\n"
    helptext+="Note2: You may remove personal data from the log file by selecting '$rdbut'.\n"
    helptext+="Note3: A list of URLs is stored in <b>$DIR_OF_CONFIG</b>.\n"

    local result=$(
        mlh_yad --list --checklist --width=800 --height=655 --text="$helptext" \
                --no-click --multiple \
                --column=Select --column="Log" --column="Description" \
                false "$journal0" "Current Boot messages" \
                false "$journal1" "Previous Boot messages"  \
                false "$journal2" "Second previous Boot messages"  \
                false "$install"  "Manjaro installer log" \
                false "$blame"    "Boot time" \
                false "$lspci"    "Display information about PCI buses as both number and device" \
                false "$lspcit"   "Display information about PCI buses as tree-like diagram" \
                false "$lsusb"    "Display information about USB buses as a tree-like diagram" \
                true "$inxi"     "Hardware information" \
                false "$rdbut"    "$rdtip" \
                false "$slbut"    "$sltip"
          )

    if [ -z "$result" ] ; then
        return
    fi

    readarray -t cmds <<< "$(echo "$result" | cut -d '|' -f 2)"

    for xx in "${cmds[@]}" ; do
        case "$xx" in
            "$journal0") Cmd pkexec $xx ;;
            "$journal1") Cmd pkexec $xx ;;
            "$journal2") Cmd pkexec $xx ;;
            "$install")  Cmd cat /var/log/Calamares.log ;;
            "$blame")    Cmd systemd-analyze blame ;;
            "$lspci")    Cmd $xx ;;
            "$lspcit")   Cmd $xx ;;
            "$lsusb")    Cmd $xx ;;
            "$inxi")     Cmd $xx ;;
        esac
    done
    if [ "$SUDO_CMDS" != ":" ] ; then
        pkexec bash -c "$SUDO_CMDS"
    fi

    for xx in "${cmds[@]}" ; do
        case "$xx" in
            "$rdbut") RemovePersonalData ;;
            "$slbut") SendToInternet ; break ;;
        esac
    done

    if [ "$isSendToInternet" > 0 ] ; then
        if [ "$removePersonalInfo" = "yes" ] ; then
            Msg "Log file <b>$FILE_OF_LOGS</b> created. Personal data was removed." "Info"
            [[ $? -eq 1 ]] && xdg-open $FILE_OF_LOGS
        else
            Msg "Log file <b>$FILE_OF_LOGS</b> created. Personal data was <b>not</b> removed." "Info"
            [[ $? -eq 1 ]] && xdg-open $FILE_OF_LOGS
        fi
    else
        echo "${FILE_OF_LOGS} Don't sent to pastebin"
    fi
}

#if [[ "$1" == "-getparts" ]]; then
#    get_Manjaro_Partitions
#fi

[[ -d "/run/miso" ]] && get_Manjaro_Partitions

Welcome
Main $@
