#!/bin/bash

## Copyright (C) 2018 - 2025 ENCRYPTED SUPPORT LLC <adrelanos@whonix.org>
## Copyright (C) 2018 Iry Koon <iry@riseup.net>
## See the file COPYING for copying conditions.

#### meta start
#### project Whonix
#### category tor
#### gateway_only yes
#### description
## helper script for <code>anon-verify</code>
#### meta end

#set -ex

temp_verbose_torrc=$(mktemp)

declare -a torrc_files

function parser() {
   local abs_path
   for abs_path in "$@"; do
      true "abs_path: '$abs_path'"
      if [[ -f "$abs_path" ]]; then
         local base_name first_character file_extension
         base_name="${abs_path##*/}"
         first_character=${base_name:0:1}
         file_extension="${base_name##*.}"

         if [ "$first_character" = "." ]; then
            printf '%s\n' "===> Ignoring file name starting with '.': $abs_path (Quote Tor manual: 'Files starting with a dot are ignored.')" | tee -a -- "$temp_verbose_torrc" >/dev/null
            continue
         fi

         if [ "$abs_path" = "/usr/share/tor/tor-service-defaults-torrc" ]; then
            true "good: $abs_path"
         elif [ "$abs_path" = "/usr/share/tor/tor-service-defaults-torrc.anondist" ]; then
            true "good: $abs_path"
         elif [ "$abs_path" = "/etc/tor/torrc" ]; then
            true "good: $abs_path"
         else
            if [ "$file_extension" = "conf" ]; then
               true "good: $abs_path"
            else
               true "extraneous: $abs_path"
               extraneous_torrc+=("$abs_path")
            fi
         fi

         printf '%s\n' "===> Start parsing file $abs_path" | tee -a -- "$temp_verbose_torrc" >/dev/null
         torrc_files+=("$abs_path")

         while read -r line ; do
            true "line: '$line'"
            if [ "$line" = "" ]; then
               ## show empty lines only when $VERY_VERBOSE is "1"
               if [ ! "$VERY_VERBOSE" = "1" ]; then
                  true "Skipping empty line."
                  continue
               fi
            fi
            ## only show comments in torrc files when $VERY_VERBOSE is "1"
            if [[ "$line" =~ ^[[:space:]]*# ]]; then
               true "line is a comment: yes"
               if [ "$VERY_VERBOSE" = "1" ]; then
                  printf '%s\n' "$line" | tee -a -- "$temp_verbose_torrc" >/dev/null
               fi
            else
               true "line is a comment: no"
               printf '%s\n' "$line" | tee -a -- "$temp_verbose_torrc" >/dev/null
            fi

            true "Checking if the line includes '%include'..."
            if printf '%s\n' "$line" | grep -- "%include" &>/dev/null ; then
               true "Yes, the line includes '%include'."
               local second_word files_list
               second_word="$(printf '%s\n' "$line" | awk '{print $2;}')"
               ## Do not quote because /etc/torrc.d/*.conf needs to be expanded.
               parser $second_word
            else
               true "No, the line does not include '%include'."
            fi
         done < "$abs_path"
         printf '%s\n' "===> Done parsing file $abs_path" | tee -a -- "$temp_verbose_torrc" >/dev/null
      elif [[ -d "$abs_path" ]]; then
         printf '%s\n' "===> Start parsing folder: $abs_path" | tee -a -- "$temp_verbose_torrc" >/dev/null
         local fso
         for fso in $(find "$abs_path" -mindepth 1 -maxdepth 1 | sort -g) ; do
            if [ -d "$fso" ]; then
               printf '%s\n' "===> Ignoring subfolder: $abs_path (Quote Tor manual: 'Files on subfolders are ignored.')" | tee -a -- "$temp_verbose_torrc" >/dev/null
               continue
            fi
            parser "$fso"
         done
         printf '%s\n' "===> Done parsing folder : $abs_path" | tee -a -- "$temp_verbose_torrc" >/dev/null
      else
         printf '%s\n' "ERROR: invalid file system object (fso) (abs_path): '$abs_path'"
      fi
   done
}

function parsing_order_verbose(){
   printf '%s\n' "The Tor configuration files are parsed in such order: "
   cat -- "$temp_verbose_torrc"
}

function used_torrc_files(){
   printf '%s\n' "${#torrc_files[@]} files are used as Tor configuration files: "
   printf '%s\n' "${torrc_files[@]}"
}

function unknown_option_specifier(){
   for unknown_option in "$@"; do
      printf '%s\n' "The following files contain unknown option '$unknown_option': "
      grep -iHnE --color -- "^([[:space:]])*$unknown_option" "${torrc_files[@]}"
      printf '%s\n' "Please modify these files to fix the problem."
   done
}

function extraneous_torrc_files(){
   if [ "$extraneous_torrc" = "" ]; then
      return 0
   fi
   printf '%s\n' "/===================================================================\\"
   printf '%s\n' "|                 Extraneous Tor Configuration Files                |"
   printf '%s\n' "\\===================================================================/"
   printf '%s\n' "${#extraneous_torrc[@]} files are do not end with file extension '.conf': "
   printf '%s\n' "${extraneous_torrc[@]}"
   printf '%s\n' "These should be probably removed."
}

#parser $@
#parsing_order_verbose
#used_torrc_files
#unknown_option_specifier "bridge" "control"
