#!/usr/bin/env bash
set -euo pipefail

REAL_IP6TABLES_RESTORE="/sbin/ip6tables-restore"
if [[ ! -x "${REAL_IP6TABLES_RESTORE}" ]]; then
    REAL_IP6TABLES_RESTORE="/usr/sbin/ip6tables-restore"
fi

cleanup() {
    [[ -n "${RULES_FILE:-}" && -f "${RULES_FILE}" ]] && rm -f "${RULES_FILE}"
    [[ -n "${SANITIZED_FILE:-}" && -f "${SANITIZED_FILE}" ]] && rm -f "${SANITIZED_FILE}"
}
trap cleanup EXIT

RULES_FILE="$(mktemp)"
cat > "${RULES_FILE}"

ipv6_unavailable() {
    local message="$1"
    [[ $message =~ [Tt]able[[:space:]]does[[:space:]]not[[:space:]]exist ]] && return 0
    [[ $message =~ address[[:space:]]family[[:space:]]not[[:space:]]supported ]] && return 0
    [[ $message =~ can[[:punct:]]t[[:space:]]initialize[[:space:]]ip6tables[[:space:]]table ]] && return 0
    [[ $message =~ IPv6[[:space:]]support[[:space:]]not[[:space:]]available ]] && return 0
    return 1
}

# First attempt with the original ruleset
output=""
if output="$(${REAL_IP6TABLES_RESTORE} "$@" < "${RULES_FILE}" 2>&1)"; then
    [[ -n "${output}" ]] && printf '%s\n' "${output}" >&2
    exit 0
fi
status=$?

# Retry without comment matches if the kernel is missing the comment module
SANITIZED_FILE="$(mktemp)"
sed -E 's/-m[[:space:]]+comment[[:space:]]+--comment[[:space:]]+"[^"]*"//g' "${RULES_FILE}" > "${SANITIZED_FILE}"

retry_output=""
if retry_output="$(${REAL_IP6TABLES_RESTORE} "$@" < "${SANITIZED_FILE}" 2>&1)"; then
    printf '%s\n' "ip6tables-restore failed with comment matches; reapplied without comments." >&2
    printf '%s\n' "Original error: ${output}" >&2
    [[ -n "${retry_output}" ]] && printf '%s\n' "${retry_output}" >&2
    exit 0
fi
retry_status=$?

# Final fallback: try legacy backend if available
legacy_output=""
for legacy in /sbin/ip6tables-restore-legacy /usr/sbin/ip6tables-restore-legacy; do
    if [[ -x "${legacy}" ]]; then
        if legacy_output="$(${legacy} "$@" < "${RULES_FILE}" 2>&1)"; then
            printf '%s\n' "ip6tables-restore failed; succeeded using legacy backend." >&2
            printf '%s\n' "Original error: ${output}" >&2
            [[ -n "${legacy_output}" ]] && printf '%s\n' "${legacy_output}" >&2
            exit 0
        fi
    fi

done

if ipv6_unavailable "${output}" || ipv6_unavailable "${retry_output}" || ipv6_unavailable "${legacy_output}"; then
    printf '%s\n' "IPv6 firewall support not detected; skipping IPv6 ruleset restore and continuing." >&2
    printf '%s\n' "Original error: ${output}" >&2
    [[ -n "${retry_output}" ]] && printf '%s\n' "Sanitized retry error: ${retry_output}" >&2
    [[ -n "${legacy_output}" ]] && printf '%s\n' "Legacy backend error: ${legacy_output}" >&2
    exit 0
fi

printf '%s\n' "ip6tables-restore failed and fallbacks were unsuccessful." >&2
printf '%s\n' "Original error: ${output}" >&2
printf '%s\n' "Sanitized retry error: ${retry_output}" >&2
exit ${retry_status}
