#!/bin/bash

# Reachability check for a peer. The meaning of "reachable" depends on kind:
#   backup-channel        At least one snapshot from this peer's hostname is
#                         visible in the configured location within the last
#                         30 days (or ever, if it's just been added).
#   direct-ssh-direct     SSH connect + 'peer-shell ping' (Phase 3).
#   direct-ssh-via-relay  Open relay session + 'peer-shell ping' (Phase 3b).
#
# Updates the peer's status + last_seen columns on success/failure so the UI
# can render a colored dot without re-running the check on every page load.

peerCheckReachable()
{
    local name="$1"
    if [[ -z "$name" ]]; then isError "peerCheckReachable: name required"; return 1; fi

    local row
    row=$(sqlite3 "$(_peerDb)" "SELECT id, kind, config_json FROM peers WHERE name='$(peerSqlEscape "$name")';" 2>/dev/null)
    if [[ -z "$row" ]]; then
        isError "No peer named '$name'"
        return 1
    fi

    local id kind cfg
    IFS='|' read -r id kind cfg <<< "$row"

    local new_status="unknown"
    local now
    now=$(date -Iseconds)

    case "$kind" in
        backup-channel)
            local hostname loc_idx
            hostname=$(printf '%s' "$cfg" | grep -o '"hostname":"[^"]*"' | head -1 | cut -d'"' -f4)
            loc_idx=$(printf '%s' "$cfg" | grep -o '"loc_idx":[0-9]*' | head -1 | cut -d':' -f2)
            if [[ -z "$hostname" ]]; then
                new_status="config-error"
            elif [[ -z "$loc_idx" ]]; then
                # No preferred location — try any enabled location.
                local found=""
                while IFS= read -r idx; do
                    [[ -z "$idx" ]] && continue
                    if engineSnapshotsJson "$idx" "" "$hostname" 2>/dev/null | grep -q '"short_id":'; then
                        found="$idx"; break
                    fi
                done < <(resticEnabledLocations)
                [[ -n "$found" ]] && new_status="ok" || new_status="no-snapshots"
            else
                if engineSnapshotsJson "$loc_idx" "" "$hostname" 2>/dev/null | grep -q '"short_id":'; then
                    new_status="ok"
                else
                    new_status="no-snapshots"
                fi
            fi
            ;;
        direct-ssh-direct|direct-ssh-via-relay)
            new_status="not-yet-implemented"
            ;;
        *)
            new_status="unknown-kind"
            ;;
    esac

    sqlite3 "$(_peerDb)" \
        "UPDATE peers SET status='$(peerSqlEscape "$new_status")', last_seen='$now' WHERE id=$id;" 2>/dev/null

    echo "$new_status"
    [[ "$new_status" == "ok" ]]
}

# Check every peer; useful for the WebUI's "Refresh" button.
peerCheckAll()
{
    local name
    while IFS= read -r name; do
        [[ -z "$name" ]] && continue
        local status
        status=$(peerCheckReachable "$name")
        isNotice "  $name → $status"
    done < <(sqlite3 "$(_peerDb)" "SELECT name FROM peers ORDER BY name;" 2>/dev/null)
}
