#!/bin/bash
#
# Titel       : GuideOS Adblocker
# Beschreibung: Zenity-basiertes Bash-Skript zum Blockieren von Werbung,
#               Malware, Phishing und weiteren unerwünschten Inhalten über /etc/hosts.
#               Unterstützt vordefinierte Blocklisten sowie benutzerdefinierte Einträge
#               und bietet eine Wiederherstellungsfunktion des Originalzustands.
# Entwickler  : evilware666 & Helga
# Version     : 2.1
# Änderungen  : Veraltete Listen wurden durch aktuellere und aktiv gepflegte Listen ersetzt
# Lizenz      : MIT
#
# Hinweis     : Erstellt ein Backup der Originaldatei /etc/hosts unter
#               /etc/hosts.adblocker.bak. Änderungen greifen systemweit
#               und können den Zugriff auf bestimmte Domains blockieren.
#               Der Browser-Cache sollte nach Änderungen ggf. geleert werden.
#
# -------------------------------------------------------
# System-Theme übernehmen
GTK_THEME=$(gsettings get org.cinnamon.desktop.interface gtk-theme | tr -d "'")
export GTK_THEME
#############################
# Globale Variablen
#############################

CUSTOM_FILE="$HOME/.adblocker_custom"
BACKUP_FILE="/etc/hosts.adblocker.bak"

# Definition der Blocklisten (Name => URL)
declare -A BLOCKLISTS

BLOCKLISTS["StevenBlack"]="https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews-gambling/hosts"
BLOCKLISTS["StevenBlack-Porn"]="https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/porn/hosts"
BLOCKLISTS["BlocklistProject-Porn"]="https://blocklistproject.github.io/Lists/porn.txt"
BLOCKLISTS["Phishing Army"]="https://phishing.army/download/phishing_hosts.txt"
BLOCKLISTS["Ultimate-Hosts-Blacklist"]="https://github.com/Ultimate-Hosts-Blacklist/Ultimate.Hosts.Blacklist/raw/master/hosts"


#############################
# Funktionen
#############################

require_sudo() {
  SUDO_PASS=$(zenity --password --title="Sudo Passwort eingeben")
  if [ -z "$SUDO_PASS" ]; then
      zenity --error --text="Kein Passwort eingegeben. Abbruch."
      exit 1
  fi
  echo "$SUDO_PASS" | sudo -S echo "Sudo-Rechte erhalten" > /dev/null 2>&1
  if [ $? -ne 0 ]; then
      zenity --error --text="Falsches Passwort oder keine sudo-Rechte. Abbruch."
      exit 1
  fi
}

run_sudo() {
  echo "$SUDO_PASS" | sudo -S "$@"
}

backup_hosts() {
  if ! sudo test -f "$BACKUP_FILE"; then
    echo "$SUDO_PASS" | sudo -S cp /etc/hosts "$BACKUP_FILE"
  fi
}

restore_hosts() {
  if sudo test -f "$BACKUP_FILE"; then
    echo "$SUDO_PASS" | sudo -S cp "$BACKUP_FILE" /etc/hosts
    if [ -f "$CUSTOM_FILE" ]; then
      rm "$CUSTOM_FILE"
    fi
    zenity --info --text="Alle vorgenommenen Einstellungen werden wieder rückgängig gemacht."
  else
    zenity --warning --text="Kein Backup gefunden – Rückgängig machen nicht möglich."
  fi
}

enable_adblock() {
  backup_hosts

  zenity --info --width=400 --height=200 --title="Wie funktioniert der Adblocker?" \
    --text="Beim Aktivieren der Blocklisten werden die ausgewählten Einträge in die Datei /etc/hosts übernommen.
Jeder Eintrag zeigt auf 0.0.0.0, wodurch die entsprechenden Domains blockiert werden.

⚠️ Hinweis: Die Änderungen gelten systemweit. Damit sie wirksam werden, ggf. den Browser-Cache leeren."

  ORIG_HOSTS=$(sudo cat "$BACKUP_FILE")
  TEMP_HOSTS=$(mktemp)
  echo "$ORIG_HOSTS" > "$TEMP_HOSTS"

  BLOCKLIST_OPTIONS=()
  for key in "${!BLOCKLISTS[@]}"; do
    DESCRIPTION=""

case "$key" in
  "Ultimate-Hosts-Blacklist") DESCRIPTION="(Malware, Ransomware, Phishing und andere Bedrohungen)" ;;
  "StevenBlack") DESCRIPTION="(Fake-News & Tracker)" ;;
  "StevenBlack-Porn") DESCRIPTION="(Pornografische Inhalte – gepflegt)" ;;
  "BlocklistProject-Porn") DESCRIPTION="(Pornografische Inhalte – gepflegt)" ;;
  "Phishing Army") DESCRIPTION="(Phishing & Fake-Shops)" ;;
esac

    BLOCKLIST_OPTIONS+=("FALSE" "$key $DESCRIPTION")
  done

  if [ -f "$CUSTOM_FILE" ]; then
    BLOCKLIST_OPTIONS+=("TRUE" "Eigene Einträge (benutzerdefiniert)")
  fi

  SELECTED=$(zenity --list --checklist \
              --title="Blocklisten auswählen" \
              --text="Wähle die Blocklisten aus, die verwendet werden sollen:" \
              --width=650 --height=300\
              --column="Auswahl" --column="Blockliste" \
              "${BLOCKLIST_OPTIONS[@]}" --separator=":")

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

  IFS=":" read -ra SELECTED_ARRAY <<< "$SELECTED"
  for list in "${SELECTED_ARRAY[@]}"; do
    CLEAN_LIST=$(echo "$list" | sed 's/ (.*)//')
    URL="${BLOCKLISTS[$CLEAN_LIST]}"
    if [ -n "$URL" ]; then
      TEMP_LIST=$(mktemp)
      curl -s "$URL" -o "$TEMP_LIST"
      if [ $? -eq 0 ]; then
         grep -E "^(0\\.0\\.0\\.0|127\\.0\\.0\\.1)" "$TEMP_LIST" >> "$TEMP_HOSTS"
      else
         zenity --warning --text="Fehler beim Herunterladen von $CLEAN_LIST."
      fi
      rm "$TEMP_LIST"
    elif [ "$CLEAN_LIST" == "Eigene Einträge (benutzerdefiniert)" ]; then
      cat "$CUSTOM_FILE" >> "$TEMP_HOSTS"
    fi
  done

  cat "$TEMP_HOSTS" | sudo tee /etc/hosts > /dev/null
  rm "$TEMP_HOSTS"
  zenity --info --text="Blocklisten wurden aktiviert."
}

add_custom_entry() {
  ENTRY=$(zenity --entry --title="Eigene Einträge" \
           --text="Gib eine Domain ein, die blockiert werden soll (z.B. ads.example.com):")
  if [ -z "$ENTRY" ]; then
    return
  fi
  if grep -q "0.0.0.0 $ENTRY" "$CUSTOM_FILE" 2>/dev/null; then
    zenity --info --text="Eintrag existiert bereits."
    return
  fi
  echo "0.0.0.0 $ENTRY" | sudo tee -a /etc/hosts > /dev/null
  echo "0.0.0.0 $ENTRY" >> "$CUSTOM_FILE"
  zenity --info --text="Eintrag wurde hinzugefügt."
}

manage_custom_entries() {
  if [ ! -f "$CUSTOM_FILE" ]; then
    zenity --info --text="Es wurden noch keine eigenen Einträge angelegt."
    return
  fi

  while true; do
    SELECTED_ENTRY=$(zenity --list --title="Eigene Einträge bearbeiten" \
      --text="Wähle einen Eintrag zum Bearbeiten oder Löschen aus:" \
      --width=600 --height=450 \
      --column="Eintrag" $(cat "$CUSTOM_FILE"))

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

    ACTION=$(zenity --list --title="Aktion wählen" \
      --text="Was möchtest du mit dem Eintrag tun?" \
      --column="Aktion" "Bearbeiten" "Löschen" "Abbrechen")

    case "$ACTION" in
      "Bearbeiten")
        NEW_ENTRY=$(zenity --entry --title="Eintrag bearbeiten" \
          --text="Gib den korrigierten Eintrag ein:" --entry-text="$(echo "$SELECTED_ENTRY" | awk '{print $2}')")
        if [ -n "$NEW_ENTRY" ]; then
          sudo sed -i "\|$SELECTED_ENTRY|d" /etc/hosts
          sed -i "\|$SELECTED_ENTRY|d" "$CUSTOM_FILE"
          echo "0.0.0.0 $NEW_ENTRY" | sudo tee -a /etc/hosts > /dev/null
          echo "0.0.0.0 $NEW_ENTRY" >> "$CUSTOM_FILE"
          zenity --info --text="Eintrag wurde geändert."
        fi
        ;;
      "Löschen")
        sudo sed -i "\|$SELECTED_ENTRY|d" /etc/hosts
        sed -i "\|$SELECTED_ENTRY|d" "$CUSTOM_FILE"
        zenity --info --text="Eintrag wurde gelöscht."
        ;;
      *)
        return
        ;;
    esac
  done
}

main_menu() {
  while true; do
    ACTION=$(zenity --list --title="Adblocker Menü" \
             --text="Wähle eine Aktion:" \
             --width=600 --height=450 \
             --column="Aktion" \
             "Blocklisten aktivieren" \
             "Eigene Einträge hinzufügen" \
             "Eigene Einträge verwalten" \
             "Blocklisten deaktivieren (Alle Einstellungen werden rückgängig gemacht.) ⚠️" \
             "Beenden")
    case "$ACTION" in
      "Blocklisten aktivieren") enable_adblock ;;
      "Blocklisten deaktivieren (Alle Einstellungen werden rückgängig gemacht.) ⚠️") restore_hosts ;;
      "Eigene Einträge hinzufügen") add_custom_entry ;;
      "Eigene Einträge verwalten") manage_custom_entries ;;
      "Beenden")
         zenity --info --title="⚠️ ACHTUNG" --text="Um die Änderungen zu übernehmen, ggf. Browser-Cache löschen."
         exit 0
         ;;
      *) return ;;
    esac
  done
}

#############################
# Hauptprogramm
#############################

require_sudo
main_menu
