#!/usr/bin/with-contenv bashio
# shellcheck shell=bash

WEBUI_PORT=${WEBUI_PORT:-8080}

export PATH="/usr/local/sbin:/usr/local/bin:${PATH}"

if bashio::config.true 'silent'; then
    sed -i 's|/proc/1/fd/1 hassio;|off;|g' /etc/nginx/nginx.conf
fi

if bashio::config.true 'openvpn_enabled'; then
    exec /usr/sbin/openvpn \
        --config /config/openvpn/config.ovpn \
        --script-security 2 \
        --up /etc/openvpn/up.sh \
        --down /etc/openvpn/down.sh \
        --pull-filter ignore "route-ipv6" \
        --pull-filter ignore "ifconfig-ipv6" \
        --pull-filter ignore "tun-ipv6" \
        --pull-filter ignore "redirect-gateway ipv6" \
        --pull-filter ignore "dhcp-option DNS6"
else
    if bashio::config.true 'wireguard_enabled'; then
        WIREGUARD_STATE_DIR="/var/run/wireguard"

        if ! bashio::fs.file_exists "${WIREGUARD_STATE_DIR}/config"; then
            bashio::exit.nok 'WireGuard runtime configuration not prepared. Please restart the add-on.'
        fi

        wireguard_config="$(cat "${WIREGUARD_STATE_DIR}/config")"
        wireguard_interface="$(cat "${WIREGUARD_STATE_DIR}/interface" 2>/dev/null || echo 'wg0')"

        if ip link show "${wireguard_interface}" &> /dev/null; then
            bashio::log.warning "WireGuard interface ${wireguard_interface} already exists. Attempting to reset it."
            wg-quick down "${wireguard_config}" >/dev/null 2>&1 || true
        fi

        bashio::log.info "Starting WireGuard interface ${wireguard_interface} using ${wireguard_config##*/}."

        if ! output=$(wg-quick up "${wireguard_config}" 2>&1); then
            bashio::log.warning 'Initial WireGuard connection attempt failed. Trying again with IPv4-only endpoints.'
            bashio::log.warning "First attempt output:${bashio::constants.LF}${output}"

            ipv4_config="${WIREGUARD_STATE_DIR}/${wireguard_interface}-ipv4.conf"
            echo -n > "${ipv4_config}"
            chmod 600 "${ipv4_config}" 2>/dev/null || true

            while IFS= read -r line; do
                if [[ "${line}" =~ ^Endpoint ]]; then
                    endpoint="${line#Endpoint = }"
                    endpoint_host="${endpoint%:*}"
                    endpoint_port="${endpoint##*:}"

                    mapfile -t ipv4_candidates < <(getent ahostsv4 "${endpoint_host}" | awk '{print $1}' | uniq)

                    if [ ${#ipv4_candidates[@]} -gt 0 ]; then
                        bashio::log.debug "Resolved ${endpoint_host} to IPv4 address ${ipv4_candidates[0]} for WireGuard fallback."
                        echo "Endpoint = ${ipv4_candidates[0]}:${endpoint_port}" >> "${ipv4_config}"
                    else
                        bashio::log.warning "No IPv4 address found for ${endpoint_host}. Keeping original endpoint for fallback."
                        echo "${line}" >> "${ipv4_config}"
                    fi
                else
                    echo "${line}" >> "${ipv4_config}"
                fi
            done < "${wireguard_config}"

            wg-quick down "${wireguard_config}" >/dev/null 2>&1 || true

            if ! output=$(wg-quick up "${ipv4_config}" 2>&1); then
                bashio::log.error 'WireGuard failed to establish a connection after IPv4-only retry.'
                bashio::log.error "wg-quick output:"
                bashio::log.error "${output}"
                bashio::log.error 'Troubleshooting steps:'
                bashio::log.error "  1. Confirm that the WireGuard configuration file '${wireguard_config}' exists inside the container and contains valid private/public keys, endpoint and AllowedIPs."
                bashio::log.error '  2. Ensure UDP port 51820 (or the port defined in your config) is forwarded on your router to this host and not blocked by your firewall or ISP.'
                bashio::log.error '  3. Verify that the configured endpoint (IP/hostname and port) is reachable from this container (e.g. ping or nc from a debug shell).'
                bashio::log.error '  4. Check that the system time is correct (NTP); large time drift can break key handshakes.'
                bashio::log.error '  5. Confirm that WireGuard kernel support / module is available in the host system.'
                bashio::log.error '  6. If DNS names are used for the endpoint, verify DNS resolution from inside the container (e.g. nslookup or dig).'
                bashio::exit.nok 'WireGuard start failed. See the log above for details.'
            fi
        fi

        bashio::log.info "WireGuard interface ${wireguard_interface} is up."

        # Refresh DNS resolver configuration if resolvconf is present
        if command -v resolvconf >/dev/null 2>&1; then
            bashio::log.info 'Refreshing DNS resolver configuration via resolvconf -u.'
            if ! resolvconf -u >/dev/null 2>&1; then
                bashio::log.warning 'resolvconf -u failed. DNS configuration may not have been updated.'
            fi
        else
            bashio::log.debug 'resolvconf not found in PATH; skipping DNS refresh.'
        fi
    fi

    if bashio::config.true 'silent'; then
        exec \
            s6-notifyoncheck -d -n 300 -w 1000 -c "nc -z localhost ${WEBUI_PORT}" \
            s6-setuidgid abc /usr/bin/qbittorrent-nox --webui-port="${WEBUI_PORT}" > /dev/null
    else
        exec \
            s6-notifyoncheck -d -n 300 -w 1000 -c "nc -z localhost ${WEBUI_PORT}" \
            s6-setuidgid abc /usr/bin/qbittorrent-nox --webui-port="${WEBUI_PORT}"
    fi
fi
