#!/bin/bash -e

###########################################################
# pt-diagnostics                                          #
#                                                         #
#   Gathers diagnostics information about pi-top hardware #
#   and software for troubleshooting purposes.            #
###########################################################

source /usr/lib/pt-diagnostics/common

if [ "$EUID" -ne 0 ]; then
    print_line_red "This program requires admin priviledges. Please run 'sudo $0'"
    exit
fi

header() {
    version_string=$(dpkg -s pt-diagnostics | grep Version:)
    current_datetime_string=$(date '+%d/%m/%Y %H:%M:%S');

    print_line_blue "===================================="
    print_line_blue "pt-diagnostics"
    print_line_blue " - Version: $version_string"
    print_line_blue " - Started: $current_datetime_string"
    print_line_blue "===================================="
    new_line

    print_line_green "Gathering data..."
    new_line
}

setup() {
    #===============================================================================
    print_line_green "$ctr. Setup"
    #===============================================================================
    #-------------------------------------------------------------------------------
    print_line_grey "   └ $ctr.1 Prepare a temporary directory for support artifacts"
    #-------------------------------------------------------------------------------

    if [ -d "$working_dir" ]; then
        rm -rf "$working_dir"
    fi

    mkdir "$working_dir"

    if [ -f "$output_file" ]; then
        rm "$output_file"
    fi

    increment_ctr
}

upgrades() {
    #===============================================================================
    print_line_green "$ctr. Upgrade logs"
    #===============================================================================

    working_dir_upgrades="$working_dir/Upgrades"

    mkdir "$working_dir_upgrades"

    #-------------------------------------------------------------------------------
    print_line_grey "   └ $ctr.1 Get the log of any recent upgrades"
    #-------------------------------------------------------------------------------

    cp "/var/log/apt/term.log" "$working_dir_upgrades"
    cp "/var/log/apt/history.log" "$working_dir_upgrades"

    increment_ctr
}

os() {
    #===============================================================================
    print_line_green "$ctr. OS"
    #===============================================================================

    working_dir_os="$working_dir/OS"

    mkdir "$working_dir_os"

    #-------------------------------------------------------------------------------
    print_line_grey "   └ $ctr.1 Get version information"
    #-------------------------------------------------------------------------------

    uname -a > "$working_dir_os/uname.log"

    #-------------------------------------------------------------------------------
    print_line_grey "   └ $ctr.2 Get boot config files"
    #-------------------------------------------------------------------------------

    cp /boot/config.txt "$working_dir_os/boot_config.txt"
    cp /boot/cmdline.txt "$working_dir_os/boot_cmdline.txt"

    #-------------------------------------------------------------------------------
    print_line_grey "   └ $ctr.3 Get boot kernel messages"
    #-------------------------------------------------------------------------------

    dmesg > "$working_dir_os/dmesg.log"

    #-------------------------------------------------------------------------------
    print_line_grey "   └ $ctr.4 Get raspi-config settings"
    #-------------------------------------------------------------------------------

    touch "$working_dir_os/raspi-config.log"

    get_raspi_config_settings "get_can_expand"                               "$working_dir_os/raspi-config.log"
    get_raspi_config_settings "get_hostname"                                 "$working_dir_os/raspi-config.log"
    get_raspi_config_settings "get_boot_cli"                                 "$working_dir_os/raspi-config.log"
    get_raspi_config_settings "get_autologin"                                "$working_dir_os/raspi-config.log"
    get_raspi_config_settings "get_boot_wait"                                "$working_dir_os/raspi-config.log"
    get_raspi_config_settings "get_boot_splash"                              "$working_dir_os/raspi-config.log"
    get_raspi_config_settings "get_overscan"                                 "$working_dir_os/raspi-config.log"
    get_raspi_config_settings "get_camera"                                   "$working_dir_os/raspi-config.log"
    get_raspi_config_settings "get_ssh"                                      "$working_dir_os/raspi-config.log"
    get_raspi_config_settings "get_vnc"                                      "$working_dir_os/raspi-config.log"
    get_raspi_config_settings "get_spi"                                      "$working_dir_os/raspi-config.log"
    get_raspi_config_settings "get_i2c"                                      "$working_dir_os/raspi-config.log"
    get_raspi_config_settings "get_serial"                                   "$working_dir_os/raspi-config.log"
    get_raspi_config_settings "get_serial_hw"                                "$working_dir_os/raspi-config.log"
    get_raspi_config_settings "get_onewire"                                  "$working_dir_os/raspi-config.log"
    get_raspi_config_settings "get_rgpio"                                    "$working_dir_os/raspi-config.log"
    get_raspi_config_settings "get_pi_type"                                  "$working_dir_os/raspi-config.log"
    get_raspi_config_settings "get_wifi_country"                             "$working_dir_os/raspi-config.log"

    #-------------------------------------------------------------------------------
    print_line_grey "   └ $ctr.5 Running processes"
    #-------------------------------------------------------------------------------

    ps aux --sort=-pcpu > "$working_dir_os/psaux.log"

    increment_ctr
}

network() {
    #===============================================================================
    print_line_green "$ctr. Network"
    #===============================================================================

    working_dir_net="$working_dir/Network"

    mkdir "$working_dir_net"

    #-------------------------------------------------------------------------------
    print_line_grey "   └ $ctr.1 Get network interface config"
    #-------------------------------------------------------------------------------

    ifconfig > "$working_dir_net/ifconfig.log"
    cp /etc/network/interfaces "$working_dir_net/interfaces"

    increment_ctr
}

installed_software() {
    #===============================================================================
    print_line_green "$ctr. Software"
    #===============================================================================

    working_dir_software="$working_dir/Software"

    mkdir "$working_dir_software"

    #-------------------------------------------------------------------------------
    print_line_grey "   └ $ctr.1 Get apt sources"
    #-------------------------------------------------------------------------------

    cp /etc/apt/sources.list.d/* "$working_dir_software"

    #-------------------------------------------------------------------------------
    print_line_grey "   └ $ctr.1 Get installed software"
    #-------------------------------------------------------------------------------

    apt list --installed > "$working_dir_software/installed_packages.log" 2>/dev/null

    increment_ctr
}

pt-os-dashboard() {
    if dpkg -s pt-os-dashboard &> /dev/null; then
        #===============================================================================
        print_line_green "$ctr. Dashboard files"
        #===============================================================================

        working_dir_dashboard="$working_dir/Dashboard"

        mkdir "$working_dir_dashboard"

        #-------------------------------------------------------------------------------
        print_line_grey "   └ $ctr.1 Get the pt-os-dashboard log files"
        #-------------------------------------------------------------------------------

        journalctl -u pt-os-dashboard --no-pager -n 5000 > "$working_dir_dashboard"/journal.log

        #-------------------------------------------------------------------------------
        print_line_grey "   └ $ctr.2 Get the pt-os-dashboard config file"
        #-------------------------------------------------------------------------------

        cp "/home/pi/.config/pi-top/pt-os-dashboard/config.json" "$working_dir_dashboard"

        #-------------------------------------------------------------------------------
        print_line_grey "   └ $ctr.3 Get other configuration files"
        #-------------------------------------------------------------------------------

        cp -rf "/etc/pi-top" "$working_dir_dashboard"

        increment_ctr
    fi
}

pt-device-manager() {
    if dpkg -s pt-device-manager &> /dev/null; then
        #===============================================================================
        print_line_green "$ctr. Device Manager"
        #===============================================================================

        working_dir_device_manager="$working_dir/DeviceManager"

        mkdir "$working_dir_device_manager"

        #-------------------------------------------------------------------------------
        print_line_grey "   └ $ctr.1 Get a log of I2C status"
        #-------------------------------------------------------------------------------

        i2cdetect -y 1 > "$working_dir_device_manager/i2cdetect.log"

        #-------------------------------------------------------------------------------
        print_line_grey "   └ $ctr.2 Get the device manager service log"
        #-------------------------------------------------------------------------------

        journalctl -u pt-device-manager > "$working_dir_device_manager/pt-device-manager.log"

        increment_ctr
    fi
}

pt-desktop()
{
    if dpkg -s pt-desktop &> /dev/null; then
        #===============================================================================
        print_line_green "$ctr. Other services"
        #===============================================================================

        working_dir_services="$working_dir/Services"

        mkdir "$working_dir_services"

        #-------------------------------------------------------------------------------
        print_line_grey "   └ $ctr.1 Get the desktop message service log"
        #-------------------------------------------------------------------------------

        journalctl -u pt-desktop-message > "$working_dir_services/pt-desktop-message.log"

        increment_ctr
    fi
}

pt_hardware_info() {
    if dpkg -s pt-diagnostics &> /dev/null; then
        #===============================================================================
        print_line_green "$ctr. Hardware"
        #===============================================================================

        working_dir_hardware="$working_dir/Hardware"

        mkdir "$working_dir_hardware"

        #-------------------------------------------------------------------------------
        print_line_grey "   └ $ctr.1 Get device register values for pi-topHUB v2"
        #-------------------------------------------------------------------------------

        /usr/lib/pt-diagnostics/pt-v2-hardware-info > "$working_dir_hardware/mcu_registers.log" 2>/dev/null

        increment_ctr
    fi
}

pt-systemd-service-status() {
    if dpkg -s pt-diagnostics &> /dev/null; then
        #===============================================================================
        print_line_green "$ctr. pi-top Systemd services"
        #===============================================================================

        working_dir_systemd="$working_dir/Systemd"

        mkdir "$working_dir_systemd"

        #-------------------------------------------------------------------------------
        print_line_grey "   └ $ctr.1 Get systemd service statuses"
        #-------------------------------------------------------------------------------

        /usr/lib/pt-diagnostics/pt-systemd-service-status > "$working_dir_systemd/service_statuses.log" 2>/dev/null

        increment_ctr
    fi
}

pt_software_info() {
    pt-os-dashboard
    pt-device-manager
    pt-desktop
    pt-systemd-service-status
}

encrypt() {
    print_line_green "Encrypting data..."
    read -p "You will now be asked to enter a passphrase. Write down or remember your passphrase! Press ENTER to continue." ok

    if [[ -f "$output_file_encrypted" ]]; then
        rm "$output_file_encrypted"
    fi
    gpg -c "$output_file"
    rm "$output_file"
    final_file="$output_file_encrypted"
}

no_encrypt() {
    print_line_red "Not encrypting data..."
    final_file="$output_file"
}

upload() {
    print_line_green "Uploading data..."

    curl --upload-file "$final_file" https://transfer.sh/
    upload_result=$?

    new_line

    if [ $upload_result -eq 0 ]; then
        print_line_green "Please provide the above URL and associated file passphrase to the pi-top support team for assistance."
        print_line "NOTE: In the event we download your diagnostic data, we will handle it in accordance with our privacy policy which you can find at https://pi-top.com/legal/privacy-policy"
    else
        print_line_red "Automatic upload of support data failed."
        no_upload_print
    fi
}

no_upload_print() {
    print_line_grey "Support data can be found here:"
    print_line "$final_file"
    print_line "Please provide the above file and associated passphrase to the pi-top support team for assistance."
    print_line "NOTE: In the event we download your diagnostic data, we will handle it in accordance with our privacy policy which you can find at https://pi-top.com/legal/privacy-policy"
}

finalise() {
    #===============================================================================
    # Compress data
    #===============================================================================

    new_line
    print_line_green "Compressing data..."

    zip -rq "$output_file" "$working_dir"

    #===============================================================================
    # Encrypt, if desired
    #===============================================================================
    while true; do
        print_line_grey "If you are intending to share this information with pi-top support, it is recommended that you protect your data with a password."
        read -p "Do you wish to encrypt your data? [y/n]  " yn
        case $yn in
            [Yy]* ) encrypt; break;;
            [Nn]* ) no_encrypt; break;;
            * ) print_line_red "Please answer [Y]es or [N]o.";;
        esac
    done

    #===============================================================================
    # Upload, if desired
    #===============================================================================
    while true; do
        print_line "If you are intending to share this information with pi-top support, an easy way of sharing them with us is by uploading to transfer.sh and sharing the URL link."
        print_line "Files uploaded to transfer.sh are stored temporarily, and removed from the server within a few days."
        read -p "Do you wish to upload your logs to https://transfer.sh?  [y/n]  " yn
        case $yn in
            [Yy]* ) upload; break;;
            [Nn]* ) no_upload_print; exit;;
            * ) print_line_red "Please answer [Y]es or [N]o.";;
        esac
    done

    new_line
    print_line_blue "Done. Exiting..."
}

header
setup
upgrades
os
network
installed_software
pt_software_info
pt_hardware_info
finalise
