#!/bin/sh
# Meshvirt Networking: validate install wizard answers before anything is
# written. Nothing here touches existing state.
# Meshvirt Networking: shared helpers for the DSM package scripts.
# Inlined into each script at packaging time in place of its "@include common"
# line (release/dist/synology/meshvirt_package.go); POSIX sh only.

PKGNAME="MeshvirtNetworking"
DEFAULT_SERVER_URL="https://mesh.meshvirt.io"

# meshvirt_pkgvar prints the directory holding state, config and logs.
meshvirt_pkgvar() {
    if [ "${SYNOPKG_DSM_VERSION_MAJOR:-7}" = "6" ]; then
        echo "/var/packages/${PKGNAME}/etc"
    elif [ -n "${SYNOPKG_PKGVAR}" ]; then
        echo "${SYNOPKG_PKGVAR}"
    else
        echo "/var/packages/${PKGNAME}/var"
    fi
}

# meshvirt_quote prints $1 single-quoted for a shell/env file.
meshvirt_quote() {
    printf "'%s'" "$(printf '%s' "$1" | sed "s/'/'\\\\''/g")"
}

# meshvirt_valid_url succeeds if $1 is https://host[:port][/path].
meshvirt_valid_url() {
    printf '%s' "$1" | grep -Eq '^https://[A-Za-z0-9.-]+(:[0-9]{1,5})?(/[^[:space:]?#]*)?$'
}

# meshvirt_valid_hostname succeeds if $1 is a DNS label.
meshvirt_valid_hostname() {
    printf '%s' "$1" | grep -Eq '^[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?$'
}

# meshvirt_valid_code succeeds if $1 looks like a pre-auth key (8-512
# characters). The length is checked separately: bounds above RE_DUP_MAX
# (255) are rejected by BSD grep.
meshvirt_valid_code() {
    [ ${#1} -ge 8 ] && [ ${#1} -le 512 ] && printf '%s' "$1" | grep -Eq '^[A-Za-z0-9_.:+=/-]+$'
}

# meshvirt_has_net_caps DAEMON succeeds if DAEMON carries cap_net_admin.
# Uses getcap when DSM has it; otherwise the marker "meshvirt configure-host"
# writes after setcap, valid only while it is newer than the binary (an
# upgrade replaces the binary and drops its capabilities).
meshvirt_has_net_caps() {
    for g in /bin/getcap /usr/bin/getcap /sbin/getcap /usr/sbin/getcap; do
        if [ -x "$g" ]; then
            "$g" "$1" 2>/dev/null | grep -q "cap_net_admin"
            return $?
        fi
    done
    marker="$(meshvirt_pkgvar)/net-caps"
    [ -f "${marker}" ] && [ "${marker}" -nt "$1" ]
}

# meshvirt_log appends a line to the package log.
meshvirt_log() {
    echo "$(date '+%Y-%m-%dT%H:%M:%S%z') $*" >>"$(meshvirt_pkgvar)/meshvirt-package.log" 2>/dev/null
}

# meshvirt_notify shows $1 in DSM's result dialog (if DSM gave us a log
# file), the package log and stderr, without failing the operation.
meshvirt_notify() {
    [ -n "${SYNOPKG_TEMP_LOGFILE}" ] && echo "$1" >>"${SYNOPKG_TEMP_LOGFILE}"
    meshvirt_log "$1"
    echo "$1" >&2
}

# meshvirt_fail reports $1 to the DSM wizard and exits non-zero.
meshvirt_fail() {
    [ -n "${SYNOPKG_TEMP_LOGFILE}" ] && echo "$1" >"${SYNOPKG_TEMP_LOGFILE}"
    echo "$1" >&2
    exit 1
}

if [ -n "${wizard_server_url}" ] && ! meshvirt_valid_url "${wizard_server_url}"; then
    meshvirt_fail "Server URL must start with https:// (for example ${DEFAULT_SERVER_URL})."
fi
if [ -n "${wizard_hostname}" ] && ! meshvirt_valid_hostname "${wizard_hostname}"; then
    meshvirt_fail "Device name may use letters, digits and hyphens (up to 63 characters)."
fi
if [ -n "${wizard_enroll_code}" ] && ! meshvirt_valid_code "${wizard_enroll_code}"; then
    meshvirt_fail "The enrollment code is not valid. Copy it again from https://enroll.meshvirt.io."
fi
exit 0
