#!/bin/bash

# Category : Networking
# Description : Wireguard Easy - VPN Server (c/u/s/r/i):

installWireguard()
{
    local config_variables="$1"

    if [[ "$wireguard" == *[cCtTuUsSrRiI]* ]]; then
        dockerConfigSetupToContainer silent wireguard;
        local app_name=$CFG_WIREGUARD_APP_NAME
		initializeAppVariables $app_name;
    fi

    if [[ "$wireguard" == *[cC]* ]]; then
        editAppConfig $app_name;
    fi

    if [[ "$wireguard" == *[uU]* ]]; then
        dockerUninstallApp $app_name;
    fi

    if [[ "$wireguard" == *[sS]* ]]; then
        dockerComposeDown $app_name;
    fi

    if [[ "$wireguard" == *[rR]* ]]; then
        dockerComposeRestart $app_name;
    fi

    if [[ "$wireguard" == *[iI]* ]]; then
        isHeader "Install $app_name"

		((menu_number++))
        echo ""
        echo "---- $menu_number. Checking if $app_name can be installed."
        echo ""

        # Host-conflict guard: a host-level WireGuard (e.g. the angristan
        # wireguard-install script — marker /etc/wireguard/params) collides with
        # this container on the wg kernel module + UDP 51820. Abort if present.
        if [[ -e /etc/wireguard/params ]]; then
            isError "WireGuard is already installed on the host — this conflicts with the $app_name app."
            isError "Installation is now aborting..."
            dockerUninstallApp "$app_name"
            return 1
        fi

		((menu_number++))
        echo ""
        echo "---- $menu_number. Setting up install folder and config file for $app_name."
        echo ""

        dockerConfigSetupToContainer "loud" "$app_name" "install" "$config_variables";
        isSuccessful "Install folders and Config files have been setup for $app_name."

        ((menu_number++))
        echo ""


		((menu_number++))
		echo ""
        echo "---- $menu_number. Setting up the $app_name docker-compose.yml file."
		echo ""

        dockerComposeSetupFile $app_name;

        monitoringToggleAppConfig "$app_name" "docker-compose.yml";

		((menu_number++))
		echo ""
        echo "---- $menu_number. Resolving wireguard tunnel subnet (WG_DEFAULT_ADDRESS)"
		echo ""

        # Generate-once-and-persist tunnel subnet. Second-octet 200-250 is
        # outside the docker network generator range (100-149), so the two
        # subnets cannot collide. Reusing the persisted value keeps existing
        # peer configs valid across reinstalls.
        local _wg_compose_for_subnet="$containers_dir$app_name/docker-compose.yml"
        if [[ -z "$CFG_WIREGUARD_SUBNET" ]]; then
            local _wg_second=$(( RANDOM % 51 + 200 ))   # 200-250
            local _wg_third=$(( RANDOM % 256 ))         # 0-255
            CFG_WIREGUARD_SUBNET="10.${_wg_second}.${_wg_third}.0"
            updateConfigOption "CFG_WIREGUARD_SUBNET" "$CFG_WIREGUARD_SUBNET"
            isSuccessful "Generated wireguard tunnel subnet: $CFG_WIREGUARD_SUBNET"
        else
            isNotice "Reusing existing wireguard tunnel subnet: $CFG_WIREGUARD_SUBNET"
        fi
        # wg-easy expects the address pattern `<base>.x` (literal x).
        local _wg_addr_pattern="${CFG_WIREGUARD_SUBNET%.0}.x"
        tagsManagerUpdateUniversalTag "$_wg_compose_for_subnet" "WIREGUARD_SUBNET_TAG" "$_wg_addr_pattern"
        isSuccessful "WG_DEFAULT_ADDRESS set to $_wg_addr_pattern"

		((menu_number++))
		echo ""
        echo "---- $menu_number. Resolving WG_HOST for peer configs"
		echo ""

        local wg_compose_file="$containers_dir$app_name/docker-compose.yml"
        local wg_host_value=""
        local _wg_traefik_installed=0
        if declare -f checkServiceInstalled >/dev/null 2>&1 && checkServiceInstalled "traefik"; then
            _wg_traefik_installed=1
        fi
        if [[ -n "$domain_full" && $_wg_traefik_installed -eq 1 ]]; then
            wg_host_value="$host_setup"
            isNotice "Domain + Traefik present — peer configs will use $wg_host_value"
        else
            wg_host_value="${public_ip_v4:-127.0.0.1}"
            if [[ -n "$domain_full" && $_wg_traefik_installed -eq 0 ]]; then
                isNotice "Domain configured but Traefik not installed — falling back to IP $wg_host_value so peer configs actually resolve."
            else
                isNotice "No domain configured — peer configs will use IP $wg_host_value (LAN only)"
            fi
        fi
        tagsManagerUpdateUniversalTag "$wg_compose_file" "PUBLIC_IP_TAG" "$wg_host_value"
        isSuccessful "WG_HOST set to $wg_host_value"

		((menu_number++))
		echo ""
        echo "---- $menu_number. Enabling IP forwarding"
		echo ""

        # Drop in /etc/sysctl.d/99-libreportal-wireguard.conf + reload — the
        # whole thing runs as root through libreportal-appcfg so the manager
        # never needs blanket /etc write or `sudo sysctl` itself.
        local result=$(runAppCfg wireguard-ip-forward)
        checkSuccess "Enabling IPv4 IP Forwarding (sysctl drop-in + reload)"

		((menu_number++))
        echo ""
        echo "---- $menu_number. Updating file permissions before starting."
        echo ""

		fixPermissionsBeforeStart $app_name;

		((menu_number++))
		echo ""
        echo "---- $menu_number. Running the docker-compose.yml to Install $app_name"
        echo ""

		dockerComposeUpdateAndStartApp $app_name install;

		((menu_number++))
		echo ""
        echo "---- $menu_number. Restarting $app_name after firewall changes"
        echo ""

        dockerComposeRestart $app_name;

        ((menu_number++))
        echo ""
        echo "---- $menu_number. Running Application specific updates (if required)"
        echo ""

        appUpdateSpecifics $app_name;

		((menu_number++))
        echo ""
        echo "---- $menu_number. Running Headscale setup (if required)"
        echo ""

		setupHeadscale $app_name;

		((menu_number++))
		echo ""
        echo "---- $menu_number. Adding $app_name to the Apps Database table."
        echo ""

		databaseInstallApp $app_name;

		((menu_number++))
        echo ""
        echo "---- $menu_number. Updating WebUI config file."
        echo ""

        webuiContainerSetup $app_name install;

		((menu_number++))
		echo ""
		echo "---- $menu_number. Refreshing monitoring integration."
		echo ""

		monitoringRefreshAll;

        ((menu_number++))
        echo ""
        echo "---- $menu_number. You can find $app_name files at $containers_dir$app_name"
        echo ""
        echo "    You can now navigate to your $app_name service using any of the options below : "
        echo ""

        menuShowFinalMessages $app_name;

		menu_number=0
        #sleep 3s
        cd
    fi
    wireguard=n
}
