#!/bin/sh
# IPv6 - fuller management for IV-BE6500

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

SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
. "$SCRIPT_DIR/lib/airwifi-auth.sh"
. "$SCRIPT_DIR/lib/airwifi-sys.sh"
require_auth

METHOD="${REQUEST_METHOD:-GET}"

ipv6_read() {
  _assign="$(uci -q get network.lan.ip6assign 2>/dev/null)"
  _lan6="$(uci -q get network.lan.ipv6 2>/dev/null)"
  _wan6_proto="$(uci -q get network.wan6.proto 2>/dev/null)"
  _wan6_if="$(uci -q get network.wan6.ifname 2>/dev/null)"
  _ra="$(uci -q get dhcp.lan.ra 2>/dev/null)"
  _dhcpv6="$(uci -q get dhcp.lan.dhcpv6 2>/dev/null)"
  _ndp="$(uci -q get dhcp.lan.ndp 2>/dev/null)"
  _ula="$(uci -q get network.globals.ula_prefix 2>/dev/null)"

  ENABLED=false
  if [ -n "$_assign" ] && [ "$_assign" != "0" ]; then ENABLED=true; fi
  if [ "$_lan6" = "0" ]; then ENABLED=false; fi
  if [ "$_wan6_proto" = "none" ] || [ "$_wan6_proto" = "disabled" ]; then
    # still allow LAN-only ipv6 if assign set
    :
  fi

  # Addresses
  WAN6_ADDR="$(ip -6 -o addr show scope global 2>/dev/null | awk '/eth0\.4|wan/{print $4; exit}')"
  LAN6_ADDR="$(ip -6 -o addr show dev br-lan scope global 2>/dev/null | awk '{print $4; exit}')"

  MODE="native"
  case "$_wan6_proto" in
    dhcpv6|dhcp) MODE="native" ;;
    static) MODE="static" ;;
    6in4|6to4|6rd) MODE="tunnel" ;;
    none|disabled|"") MODE="disabled"; ENABLED=false ;;
  esac
  [ "$ENABLED" = "false" ] && MODE="disabled"

  RA_MODE="${_ra:-hybrid}"
  DHCPV6_MODE="${_dhcpv6:-hybrid}"
}

ipv6_apply() {
  _en="$1"
  _mode="$2"
  _ra="$3"
  _dhcpv6="$4"

  aw_ensure_airwifi
  uci -q get network.wan6 >/dev/null 2>&1 || {
    uci set network.wan6=interface
    uci set network.wan6.ifname='@wan'
  }

  if [ "$_en" != "true" ] || [ "$_mode" = "disabled" ]; then
    uci set network.lan.ip6assign='0'
    uci set network.lan.ipv6='0'
    uci set network.wan6.proto='none'
    uci set dhcp.lan.ra='disabled'
    uci set dhcp.lan.dhcpv6='disabled'
    uci set dhcp.lan.ndp='disabled'
  else
    uci set network.lan.ipv6='1'
    uci set network.lan.ip6assign='64'
    uci set network.lan.ip6ifaceid='eui64'
    case "$_mode" in
      static)
        uci set network.wan6.proto='static'
        ;;
      tunnel)
        # keep existing tunnel if any; default dhcpv6 otherwise
        _cur="$(uci -q get network.wan6.proto 2>/dev/null)"
        case "$_cur" in 6in4|6to4|6rd) ;; *) uci set network.wan6.proto='dhcpv6' ;; esac
        ;;
      *)
        uci set network.wan6.proto='dhcpv6'
        uci set network.wan6.ifname='@wan'
        ;;
    esac
    [ -n "$_ra" ] && uci set dhcp.lan.ra="$_ra" || uci set dhcp.lan.ra='hybrid'
    [ -n "$_dhcpv6" ] && uci set dhcp.lan.dhcpv6="$_dhcpv6" || uci set dhcp.lan.dhcpv6='hybrid'
    uci set dhcp.lan.ndp='hybrid'
  fi
  uci commit network
  uci commit dhcp
  (
    /etc/init.d/network reload >/dev/null 2>&1
    /etc/init.d/odhcpd restart >/dev/null 2>&1
  ) >>/tmp/airwifi-ipv6.log 2>&1 &
}

if [ "$METHOD" = "GET" ]; then
  ipv6_read
  json_response "200 OK" "{\"ok\":true,\"ipv6\":{\"enabled\":$ENABLED,\"mode\":\"$MODE\",\"ra\":\"$RA_MODE\",\"dhcpv6\":\"$DHCPV6_MODE\",\"ula\":\"$(aw_json_escape "$_ula")\",\"wan6_addr\":\"$(aw_json_escape "$WAN6_ADDR")\",\"lan6_addr\":\"$(aw_json_escape "$LAN6_ADDR")\",\"wan6_proto\":\"$(aw_json_escape "$_wan6_proto")\"}}"
  exit 0
fi

if [ "$METHOD" = "POST" ]; then
  BODY="$(cat)"
  ENABLED="$(printf '%s' "$BODY" | jsonfilter -e '@.enabled' 2>/dev/null)"
  MODE="$(printf '%s' "$BODY" | jsonfilter -e '@.mode' 2>/dev/null)"
  RA="$(printf '%s' "$BODY" | jsonfilter -e '@.ra' 2>/dev/null)"
  DHCPV6="$(printf '%s' "$BODY" | jsonfilter -e '@.dhcpv6' 2>/dev/null)"
  # Backward compatible: only enabled from old UI
  [ -z "$MODE" ] && {
    case "$ENABLED" in true|1) MODE="native" ;; *) MODE="disabled" ;; esac
  }
  case "$ENABLED" in true|1|True) ENABLED=true ;; *) ENABLED=false ;; esac
  ipv6_apply "$ENABLED" "$MODE" "$RA" "$DHCPV6"
  json_response "200 OK" '{"ok":true}'
  exit 0
fi

json_response "405 Method Not Allowed" '{"ok":false,"error":"method_not_allowed"}'
