#!/bin/bash
#
# SxLoadCheck
# Version : 0.8
# Author  : Christophe Casalegno / Brain 0verride
#
# License : GPL-3.0 or later
#
# Copyright (c) 2025 Christophe Casalegno
#
# 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, either version 3 of the License, or
#    (at your option) any later version.
#
#    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.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <https://www.gnu.org/licenses/>
#
# The license is available on this server here:
# https://www.christophe-casalegno.com/licences/gpl-3.0.txt
#
# Description: Compare TLS/DNS/TTFB/load time between multiple domains
#              Optionally includes DNS diagnostics (light or deep).
#
# Requires: curl, dig, whois

domains=()
dns_check=false
deep_dns=false

function show_help()
{
    echo "Usage: $0 --domains domain1.com,domain2.com[,domainN.com] [--dns-check] [--deep-dns]"
    echo
    echo "Options:"
    echo "  --domains     Comma-separated list of domains to test (required)"
    echo "  --dns-check   Run a quick DNS diagnostic (resolver timing, TTL, NS)"
    echo "  --deep-dns    Run a deep DNS diagnostic (trace, glue, SOA, A)"
    echo
    exit 1
}

while [[ $# -gt 0 ]]
do
    case "$1" in
        --domains)
            if [[ -z "$2" ]]
            then
                echo "Error: missing argument for --domains"
                exit 2
            fi

            echo "$2" | grep -qE '[ ;]' && {
                echo "Error: invalid separator detected in domain list. Use only commas."
                echo "Example: --domains domain1.com,domain2.com"
                exit 2
            }

            IFS=',' read -ra domains <<< "$2"
            shift 2
        ;;
        --dns-check)
            dns_check=true
            shift
        ;;
        --deep-dns)
            deep_dns=true
            shift
        ;;
        --help|-h)
            show_help
        ;;
        *)
            echo "Unknown option: $1"
            show_help
        ;;
    esac
done

if [[ ${#domains[@]} -eq 0 ]]
then
    echo "Error: no domains provided."
    show_help
fi

invalids=()
for domain in "${domains[@]}"
do
    echo "$domain" | grep -qE '^([a-zA-Z0-9][-a-zA-Z0-9]*\.)+[a-zA-Z]{2,}$' || invalids+=("$domain")
done

if [[ ${#invalids[@]} -gt 0 ]]
then
    echo "Error: the following entries are not valid FQDNs:"
    for d in "${invalids[@]}"
    do
        echo "  - $d"
    done
    echo
    exit 2
fi

curl_format=$(
cat <<EOF

Domain:        %{url_effective}
DNS Lookup:    %{time_namelookup}s
TCP Connect:   %{time_connect}s
TLS Handshake: %{time_appconnect}s
TTFB:          %{time_starttransfer}s
Total Time:    %{time_total}s
----------------------------

EOF
)

dns_check_light()
{
    local domain="$1"
    echo "→ DNS quick check for $domain"
    echo

    echo '- Resolver timings:'
    for resolver in 1.1.1.1 8.8.8.8 9.9.9.9 208.67.222.222
    do
        time_ms=$(dig @$resolver +stats +time=2 "$domain" | grep "Query time" | awk '{print $4}')
        printf "  @%-14s → %s ms\n" "$resolver" "$time_ms"
    done

    echo
    echo '- TTL:'
    dig "$domain" +noall +answer | grep -E 'IN\s+A' | awk '{print "  "$1": TTL = "$2"s"}'

    echo
    echo '- NS Records:'
    dig "$domain" NS +short | sed 's/^/  /'

    echo
    echo '----------------------------'
    echo
}

dns_check_deep()
{
    local domain="$1"
    echo "→ DNS deep check for $domain"
    echo

    echo '- Full DNS trace:'
    dig +trace "$domain"

    echo
    echo '- Glue and delegation check:'
    whois "$domain" | grep -Ei 'nserver|dns|Name Server'

    echo
    echo '- SOA record:'
    dig "$domain" SOA +short

    echo
    echo '- A record details:'
    dig "$domain" A +noall +answer

    echo '----------------------------'
    echo
}

echo
echo "=== StackX Load Time Diagnostic ==="
echo

for domain in "${domains[@]}"
do
    echo "Testing $domain..."
    curl -s -o /dev/null -w "$curl_format" --user-agent "ScalarXMonitor/1.0" "https://$domain"

    if $dns_check
    then
        dns_check_light "$domain"
    fi

    if $deep_dns
    then
        dns_check_deep "$domain"
    fi
done

