#!/usr/bin/env bash

# Diagnostic script for Multipass on Mac (Ubuntu 24.04 guest)
# Counterpart of check_v6.sh (WSL version)

# NOTE: set -e is intentionally omitted because this is a diagnostic script
# that must continue running even when individual checks fail.
set -u
umask 022

LOGFILE="/var/log/check.log"

TINET_SOURCE="/mnt/c/tinet/tinet"
TINET_DEST="/usr/bin/tinet"

RESOLVED_CONF="/etc/systemd/resolved.conf"
RESOLVED_LINE="DNS=8.8.8.8 1.1.1.1"

PASS_COUNT=0
WARN_COUNT=0
FAIL_COUNT=0
FAIL_REASONS=()

###############################################################################
# Logging
###############################################################################

log() {
    printf '%s\n' "$1" | tee -a "$LOGFILE"
}

log_only() {
    printf '%s\n' "$1" >> "$LOGFILE"
}

section() {
    printf '\n========================================================\n' | tee -a "$LOGFILE"
    printf '%s\n' "$1" | tee -a "$LOGFILE"
    printf '========================================================\n' | tee -a "$LOGFILE"
}

pass() {
    PASS_COUNT=$((PASS_COUNT + 1))
    log "[OK]   $1"
}

warn() {
    WARN_COUNT=$((WARN_COUNT + 1))
    log "[WARN] $1"
}

fail_check() {
    FAIL_COUNT=$((FAIL_COUNT + 1))
    FAIL_REASONS+=("$1")
    log "[FAIL] $1"
}

info() {
    log "[INFO] $1"
}

###############################################################################
# Helpers
###############################################################################

command_exists() {
    command -v "$1" >/dev/null 2>&1
}

is_multipass() {
    systemd-detect-virt 2>/dev/null | grep -qi qemu
}

###############################################################################
# Diagnostics
###############################################################################

check_environment() {
    section "Environment"

    if is_multipass; then
        pass "This environment appears to be running under Multipass (QEMU)."
    else
        warn "This environment does not appear to be Multipass (QEMU)."
        info "Detected virt: $(systemd-detect-virt 2>/dev/null || echo unknown)"
    fi

    if [ -f /proc/version ]; then
        log_only ""
        log_only "----- /proc/version -----"
        cat /proc/version >> "$LOGFILE"
        log_only "-------------------------"
    fi

    if [ -f /etc/os-release ]; then
        log_only ""
        log_only "----- /etc/os-release -----"
        cat /etc/os-release >> "$LOGFILE"
        log_only "---------------------------"
    fi

    info "Current user: $(id -un)"
    info "Hostname: $(hostname)"
    info "Current shell: ${SHELL:-unknown}"
}

check_dns() {
    section "DNS (systemd-resolved)"

    if [ ! -f "$RESOLVED_CONF" ]; then
        fail_check "$RESOLVED_CONF does not exist."
        return
    fi

    pass "$RESOLVED_CONF exists."

    log_only ""
    log_only "----- $RESOLVED_CONF -----"
    cat "$RESOLVED_CONF" >> "$LOGFILE"
    log_only "--------------------------"

    if grep -q "^${RESOLVED_LINE}$" "$RESOLVED_CONF" 2>/dev/null; then
        pass "DNS is configured correctly (${RESOLVED_LINE})."
    else
        fail_check "DNS line '${RESOLVED_LINE}' not found in $RESOLVED_CONF."
    fi

    if command_exists resolvectl; then
        log_only ""
        log_only "----- resolvectl status -----"
        resolvectl status >> "$LOGFILE" 2>&1 || true
        log_only "-----------------------------"
    fi
}

check_boot_settings() {
    section "Boot and systemd"

    if [ -d /run/systemd/system ]; then
        pass "systemd appears to be active."
    else
        fail_check "systemd does not appear to be active."
    fi

    if command_exists systemctl; then
        pass "'systemctl' command is available."
    else
        fail_check "'systemctl' command is not available."
    fi
}

check_network() {
    section "Network"

    if command_exists ip; then
        pass "'ip' command is available."

        log_only ""
        log_only "----- ip addr -----"
        ip addr >> "$LOGFILE" 2>&1
        log_only "-------------------"

        log_only ""
        log_only "----- ip route -----"
        ip route >> "$LOGFILE" 2>&1
        log_only "--------------------"
    else
        fail_check "'ip' command is not available."
    fi

    if ping -c 2 8.8.8.8 >> "$LOGFILE" 2>&1; then
        pass "Outbound connectivity to 8.8.8.8 is working."
    else
        fail_check "Outbound connectivity to 8.8.8.8 failed."
    fi

    log_only ""
    log_only "----- resolvectl dns -----"
    resolvectl dns >> "$LOGFILE" 2>&1
    log_only "--------------------------"

    if resolvectl query google.com >> "$LOGFILE" 2>&1; then
        pass "DNS resolution is working (google.com)."
    else
        fail_check "DNS resolution failed (google.com)."
    fi
}

check_docker() {
    section "Docker"

    if dpkg -s docker.io >/dev/null 2>&1; then
        pass "docker.io package is installed."
    elif dpkg -s docker-ce >/dev/null 2>&1; then
        warn "docker-ce package is installed (expected docker.io)."
    else
        fail_check "No Docker package is installed (docker.io or docker-ce)."
    fi

    if command_exists docker; then
        pass "'docker' command is available."
        info "Docker version: $(docker --version 2>/dev/null || echo unknown)"
    else
        fail_check "'docker' command is not available."
    fi

    if ! command_exists systemctl; then
        fail_check "'systemctl' command is not available."
        return
    fi

    pass "'systemctl' command is available for Docker checks."

    if systemctl is-enabled docker >/dev/null 2>&1; then
        pass "docker.service is enabled."
    else
        fail_check "docker.service is not enabled."
    fi

    local docker_active=false
    if systemctl is-active docker >/dev/null 2>&1; then
        docker_active=true
        pass "docker.service is running."
    else
        fail_check "docker.service is not running."
    fi

    if systemctl is-enabled docker.socket >/dev/null 2>&1; then
        pass "docker.socket is enabled."
    else
        warn "docker.socket is not enabled."
    fi

    # If docker.socket is active while docker.service is running, that is normal.
    # If only the socket is active and the service is stopped, report it as a warning.
    if systemctl is-active docker.socket >/dev/null 2>&1; then
        if [ "$docker_active" = true ]; then
            pass "docker.socket is active."
        else
            warn "docker.socket is active but docker.service is not running (socket-only state)."
        fi
    else
        pass "docker.socket is not active."
    fi

    log_only ""
    log_only "----- systemctl status docker --no-pager -----"
    systemctl status docker --no-pager >> "$LOGFILE" 2>&1 || true
    log_only "----------------------------------------------"

    log_only ""
    log_only "----- systemctl status docker.socket --no-pager -----"
    systemctl status docker.socket --no-pager >> "$LOGFILE" 2>&1 || true
    log_only "-----------------------------------------------------"
}

check_tinet() {
    section "tinet"

    if [ -x "$TINET_DEST" ]; then
        pass "tinet is installed at $TINET_DEST."
    else
        fail_check "tinet is not installed at $TINET_DEST."
    fi

    if [ -f "$TINET_SOURCE" ]; then
        pass "Source tinet file exists at $TINET_SOURCE."
    else
        warn "Source tinet file does not exist at $TINET_SOURCE."
    fi
}

print_summary() {
    section "Summary"

    log "Passed  : $PASS_COUNT"
    log "Warnings: $WARN_COUNT"
    log "Failed  : $FAIL_COUNT"
    log ""
    log "Diagnostic log file: $LOGFILE"

    if [ "$FAIL_COUNT" -eq 0 ]; then
        log ""
        if [ "$WARN_COUNT" -eq 0 ]; then
            log "Overall result: ALL CHECKS PASSED"
        else
            log "Overall result: ALL CHECKS PASSED (with warnings)"
        fi
    else
        log ""
        log "Overall result: SOME CHECKS FAILED"
        log ""
        log "Failed checks:"
        if [ "${#FAIL_REASONS[@]}" -gt 0 ]; then
            local reason
            for reason in "${FAIL_REASONS[@]}"; do
                log "  - $reason"
            done
        fi
    fi
}

###############################################################################
# Main
###############################################################################

main() {
    if [ "$(id -u)" -ne 0 ]; then
        echo "ERROR: This script must be run as root." >&2
        exit 1
    fi

    : > "$LOGFILE"

    section "Starting diagnostic (Multipass)"

    check_environment
    check_dns
    check_boot_settings
    check_network
    check_docker
    check_tinet
    print_summary
}

main "$@"
