# Copyright (c) 2021-2026 community-scripts ORG
# Author: tteck (tteckster)
# Co-Author: MickLesk
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE

if ! command -v curl >/dev/null 2>&1; then
  apk update && apk add curl >/dev/null 2>&1
fi
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
load_functions
catch_errors

# Persist diagnostics setting inside container (exported from build.func)
# so addon scripts running later can find the user's choice
if [[ ! -f /usr/local/community-scripts/diagnostics ]]; then
  mkdir -p /usr/local/community-scripts
  echo "DIAGNOSTICS=${DIAGNOSTICS:-no}" >/usr/local/community-scripts/diagnostics
fi

# Get LXC IP address (must be called INSIDE container, after network is up)
get_lxc_ip

# ------------------------------------------------------------------------------
# post_progress_to_api()
#
# - Lightweight progress ping from inside the container
# - Updates the existing telemetry record status
# - Arguments:
#   * $1: status (optional, default: "configuring")
# - Signals that the installation is actively progressing (not stuck)
# - Fire-and-forget: never blocks or fails the script
# - Only executes if DIAGNOSTICS=yes and RANDOM_UUID is set
# ------------------------------------------------------------------------------
post_progress_to_api() {
  command -v curl &>/dev/null || return 0
  [[ "${DIAGNOSTICS:-no}" == "no" ]] && return 0
  [[ -z "${RANDOM_UUID:-}" ]] && return 0

  local progress_status="${1:-configuring}"

  curl -fsS -m 5 -X POST "https://telemetry.community-scripts.org/telemetry" \
    -H "Content-Type: application/json" \
    -d "{\"random_id\":\"${RANDOM_UUID}\",\"execution_id\":\"${EXECUTION_ID:-${RANDOM_UUID}}\",\"type\":\"lxc\",\"nsapp\":\"${app:-unknown}\",\"status\":\"${progress_status}\"}" &>/dev/null || true
}

# This function enables IPv6 if it's not disabled and sets verbose mode
verb_ip6() {
  set_std_mode # Set STD mode based on VERBOSE

  if [ "${IPV6_METHOD:-}" = "disable" ]; then
    msg_info "Disabling IPv6 (this may affect some services)"
    $STD sysctl -w net.ipv6.conf.all.disable_ipv6=1
    $STD sysctl -w net.ipv6.conf.default.disable_ipv6=1
    $STD sysctl -w net.ipv6.conf.lo.disable_ipv6=1
    mkdir -p /etc/sysctl.d
    $STD tee /etc/sysctl.d/99-disable-ipv6.conf >/dev/null <<EOF
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
EOF
    $STD rc-update add sysctl default
    msg_ok "Disabled IPv6"
  fi
}

# This function sets up the Container OS by generating the locale, setting the timezone, and checking the network connection
setting_up_container() {
  msg_info "Setting up Container OS"
  while [ $i -gt 0 ]; do
    if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" != "" ]; then
      break
    fi
    echo 1>&2 -en "${CROSS}${RD} No Network! "
    sleep $RETRY_EVERY
    i=$((i - 1))
  done

  if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" = "" ]; then
    echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}"
    echo -e "${NETWORK}Check Network Settings"
    exit 121
  fi
  msg_ok "Set up Container OS"
  msg_ok "Network Connected: ${BL}$(ip addr show | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1 | tail -n1)${CL}"
  post_progress_to_api
}

# This function checks the network connection by pinging a known IP address and prompts the user to continue if the internet is not connected
network_check() {
  set +e
  trap - ERR
  ipv4_connected=false

  # Check IPv4 connectivity to Cloudflare, Google & Quad9 DNS servers
  if ping -c 1 -W 1 1.1.1.1 &>/dev/null || ping -c 1 -W 1 8.8.8.8 &>/dev/null || ping -c 1 -W 1 9.9.9.9 &>/dev/null; then
    msg_ok "IPv4 Internet Connected"
    ipv4_connected=true
  else
    msg_error "IPv4 Internet Not Connected"
  fi

  if [[ $ipv4_connected == false ]]; then
    read -r -p "No Internet detected, would you like to continue anyway? <y/N> " prompt
    if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
      echo -e "${INFO}${RD}Expect Issues Without Internet${CL}"
    else
      echo -e "${NETWORK}Check Network Settings"
      exit 122
    fi
  fi

  # DNS resolution checks for GitHub-related domains
  GIT_HOSTS=("github.com" "raw.githubusercontent.com" "api.github.com" "git.community-scripts.org")
  GIT_STATUS="Git DNS:"
  DNS_FAILED=false

  for HOST in "${GIT_HOSTS[@]}"; do
    RESOLVEDIP=$(getent hosts "$HOST" | awk '{ print $1 }' | grep -E '(^([0-9]{1,3}\.){3}[0-9]{1,3}$)|(^[a-fA-F0-9:]+$)' | head -n1)
    if [[ -z "$RESOLVEDIP" ]]; then
      GIT_STATUS+="$HOST:($DNSFAIL)"
      DNS_FAILED=true
    else
      GIT_STATUS+=" $HOST:($DNSOK)"
    fi
  done

  if [[ "$DNS_FAILED" == true ]]; then
    fatal "$GIT_STATUS"
  else
    msg_ok "$GIT_STATUS"
  fi

  set -e
  trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
}

# This function updates the Container OS by running apk upgrade with mirror fallback
update_os() {
  msg_info "Updating Container OS"
  if ! $STD apk -U upgrade; then
    msg_warn "apk update failed (dl-cdn.alpinelinux.org), trying alternate mirrors..."
    local alpine_mirrors="mirror.init7.net ftp.halifax.rwth-aachen.de mirrors.edge.kernel.org alpine.mirror.wearetriple.com mirror.leaseweb.com uk.alpinelinux.org dl-2.alpinelinux.org dl-4.alpinelinux.org"
    local apk_ok=false
    for m in $(printf '%s\n' $alpine_mirrors | shuf); do
      if timeout 2 bash -c "echo >/dev/tcp/$m/80" 2>/dev/null; then
        msg_custom "${INFO}" "${YW}" "Attempting mirror: ${m}"
        cat <<EOF >/etc/apk/repositories
http://$m/alpine/latest-stable/main
http://$m/alpine/latest-stable/community
EOF
        if $STD apk -U upgrade; then
          msg_ok "CDN set to ${m}: tests passed"
          apk_ok=true
          break
        else
          msg_warn "Mirror ${m} failed"
        fi
      fi
    done
    if [[ "$apk_ok" != true ]]; then
      msg_error "All Alpine mirrors failed. Check network or try again later."
      exit 1
    fi
  fi
  local tools_content
  tools_content=$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) || {
    msg_error "Failed to download tools.func"
    exit 115
  }
  source /dev/stdin <<<"$tools_content"
  if ! declare -f fetch_and_deploy_gh_release >/dev/null 2>&1; then
    msg_error "tools.func loaded but incomplete — missing expected functions"
    exit 115
  fi
  msg_ok "Updated Container OS"
  post_progress_to_api
}

# This function modifies the message of the day (motd) and SSH settings
motd_ssh() {
  echo "export TERM='xterm-256color'" >>/root/.bashrc

  PROFILE_FILE="/etc/profile.d/00_lxc-details.sh"
  echo "echo -e \"\"" >"$PROFILE_FILE"
  echo -e "echo -e \"${BOLD}${APPLICATION} LXC Container${CL}"\" >>"$PROFILE_FILE"
  echo -e "echo -e \"${TAB}${GATEWAY}${YW} Provided by: ${GN}community-scripts ORG ${YW}| GitHub: ${GN}https://github.com/community-scripts/ProxmoxVE${CL}\"" >>"$PROFILE_FILE"
  echo "echo \"\"" >>"$PROFILE_FILE"
  echo -e "echo -e \"${TAB}${OS}${YW} OS: ${GN}\$(grep ^NAME /etc/os-release | cut -d= -f2 | tr -d '\"') - Version: \$(grep ^VERSION_ID /etc/os-release | cut -d= -f2 | tr -d '\"')${CL}\"" >>"$PROFILE_FILE"
  echo -e "echo -e \"${TAB}${HOSTNAME}${YW} Hostname: ${GN}\$(hostname)${CL}\"" >>"$PROFILE_FILE"
  echo -e "echo -e \"${TAB}${INFO}${YW} IP Address: ${GN}\$(ip -4 addr show eth0 | awk '/inet / {print \$2}' | cut -d/ -f1 | head -n 1)${CL}\"" >>"$PROFILE_FILE"

  # Configure SSH if enabled
  if [[ "${SSH_ROOT}" == "yes" ]]; then
    # Enable sshd service
    $STD rc-update add sshd
    # Allow root login via SSH
    sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config
    # Start the sshd service
    $STD /etc/init.d/sshd start
  fi
  post_progress_to_api
}

# Validate Timezone for some LXC's
validate_tz() {
  [[ -f "/usr/share/zoneinfo/$1" ]]
}

# This function customizes the container and enables passwordless login for the root user
customize() {
  if [[ "$PASSWORD" == "" ]]; then
    msg_info "Customizing Container"
    passwd -d root >/dev/null 2>&1

    # Ensure agetty is available
    apk add --no-cache --force-broken-world util-linux >/dev/null 2>&1

    # Create persistent autologin boot script
    mkdir -p /etc/local.d
    cat <<'EOF' >/etc/local.d/autologin.start
#!/bin/sh
sed -i 's|^tty1::respawn:.*|tty1::respawn:/sbin/agetty --autologin root --noclear tty1 38400 linux|' /etc/inittab
kill -HUP 1
EOF
    touch /root/.hushlogin

    chmod +x /etc/local.d/autologin.start
    rc-update add local >/dev/null 2>&1

    # Apply autologin immediately for current session
    /etc/local.d/autologin.start

    msg_ok "Customized Container"
  fi

  echo "bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/${app}.sh)\"" >/usr/bin/update
  chmod +x /usr/bin/update
  post_progress_to_api
}
