#!/bin/sh
set -e
if ls -1 /lib | grep -q ld-musl
then
  [ -e /lib/arm-linux-gnueabihf ] || ln -s /usr/share/speedify/lib/arm-linux-gnueabihf /lib/arm-linux-gnueabihf
  [ -e /lib/ld-linux-armhf.so.3 ] || ln -s /usr/share/speedify/lib/ld-linux-armhf.so.3 /lib/ld-linux-armhf.so.3
fi
name_of_kv() {
  echo "$1" | cut -d= -f1
}
# Wraps the connectify0 TUN network interface in a UCI-friendly network interface.
# Useful when references in other parts of UCI, like the network and firewall configs.
install_network_speedify() {
  uci show network | grep -q connectify0 || uci batch <<EOI
  add network device
  set network.@device[-1].name=connectify0
  set network.@device[-1].acceptlocal=1
EOI
  uci show network.speedify 2> /dev/null || uci batch <<EOI
  set network.speedify=interface
  set network.speedify.proto=none
  set network.speedify.device=connectify0
  set network.speedify.defaultroute=0
  add_list network.speedify.dns=10.202.0.1
EOI
}
# - Gives speedify membership in the lan and wan zones.
# - Creates a new zone, speedify.
# - Allows traffic to/from the lan and speedify.
install_firewall_speedify() {
  uci show firewall | grep -E "@zone\[[0-9]+\].name='[lw]an(6|)'" | uniq | sort -r | while read name
  do
    zone=$(echo "$name" | cut -d. -f2)
    if uci show "firewall.$zone.device" 2> /dev/null | grep -q connectify0
    then echo "firewall.$zone.device: Tun dev connectify0 already has membership"
    else
      echo "Adding tun dev connectify0 to firewall.$zone.device"
      existing_associated_devices() {
        uci show "firewall.$zone" | grep '.device=' | cut -d. -f3 | cut -d= -f2 | grep -v connectify0 | tr '\n' ' '
      }
      uci add_list "firewall.$zone.device=connectify0"
    fi
  done
  mk_sfy_zone() {
    uci batch <<EOI
    add firewall zone # A new zone, now the last one
    set firewall.@zone[-1].name=speedify
    set firewall.@zone[-1].input=ACCEPT
    set firewall.@zone[-1].output=ACCEPT
    set firewall.@zone[-1].forward=ACCEPT
    add_list firewall.@zone[-1].device=connectify0
    add_list firewall.@zone[-1].network=speedify
    add firewall forwarding # speedify -> lan
    set firewall.@forwarding[-1].src=speedify
    set firewall.@forwarding[-1].dest=lan
    add firewall forwarding # lan -> speedify
    set firewall.@forwarding[-1].src=lan
    set firewall.@forwarding[-1].dest=speedify
EOI
  }
  sfy_zones() {
    ( uci show firewall | grep -E "@zone\\[[0-9]+\\].name='speedify'" || true ) | cut -d= -f1
  }
  case "$(sfy_zones | grep -c .)" in
    0)
      echo "No firewall zone for Speedify found, creating..."
      mk_sfy_zone
      ;;
    1)
      echo "Firewall zone for Speedify already exists, skipping firewall zone creation."
      ;;
    *)
      echo "Multiple firewall zones for Speedify found, pruning..."
      sfy_zones | sort -r | while read zone
      do uci delete "$zone" 2> /dev/null || echo "Failed: uci delete $zone"
      done
      uci commit || echo "Failed: uci commit"
      mk_sfy_zone
      ;;
  esac
}
ec=0
echo "Installing network and firewall rules for Speedify..."
install_firewall_speedify || ec=$?
install_network_speedify || ec=$?
uci commit || ec=$?
echo "Restarting the network and firewall after rule changes..."

/etc/init.d/firewall restart &> /tmp/speedify-postinst-err-log.txt || {
  ec=$?
  echo "Firewall restart failed (ec: $ec) with errors:"
  cat /tmp/speedify-postinst-err-log.txt
}
/etc/init.d/network restart &> /tmp/speedify-postinst-err-log.txt || {
  ec=$?
  echo "Network restart failed (ec: $ec) with errors:"
  cat /tmp/speedify-postinst-err-log.txt
}
rm -f /tmp/speedify-postinst-err-log.txt
echo "Starting and enabling Speedify's system service..."
/etc/init.d/speedify enable || ec=$?
/etc/init.d/speedify start || ec=$?
if [ $ec -eq 0 ]
then echo "Successfully created Speedify's network, firewall and system service"
else echo "Errors occurred while creating Speedify's network, firewall or system service"
fi
exit $ec
