#!/bin/bash

function is_online_with {
  URL="$1"
  UPDOWN="$2"
  STATUS=""
  isonlinewith="unknown"
  if test -n "$URL" -a -n "$UPDOWN"; then 
    for i in $( seq 1 10 ) #{
    do
      read STATUS < <(
        /usr/bin/curl -sI "$URL" |
        $TR -d '\r' |
        /usr/bin/awk '/^X-Networkmanager-Status:/ { STATUS = $2 } 
             END { printf( "%s\n", STATUS ) }'
      )
      if test -n "$STATUS" -a "$STATUS" = "online"; then
        isonlinewith="yes"
        test "$UPDOWN" = "up" && break
      else
        isonlinewith="no"
        test "$UPDOWN" = "down" && break
      fi
      sleep 1
    done 
  fi 
  echo "$isonlinewith"
} 

function iftype_get {
  local INTERFACE="$1"
  local IFTYPE=""
  case "$INTERFACE" in
  '') ;;
  lte[0-9]) IFTYPE="gsm" ;;
  *)
    IFTYPE=$( \
      /usr/bin/nmcli --terse --fields "GENERAL.TYPE" device show \
                     "$INTERFACE" \
      | /usr/bin/cut -d: -f2 \
    )
    ;;
  esac
  echo "$IFTYPE"
} # // end iftype_get

function iftype_by_con_get {
  local CON_UUID="$1"
  local IFTYPE=""
  IFTYPE=$( \
    /usr/bin/nmcli --terse --fields "connection.type" con show \
                   "$CON_UUID" \
    | /usr/bin/cut -d: -f2 \
  )
  echo "$IFTYPE"
} # // end iftype_by_con_get

function ntp2timesyncd {
  local MYACTION="$1"
  local CON_UUID="$2"
  test -z "$MYACTION" -o -z "$CON_UUID" && return
  local IFTYPE=$( iftype_by_con_get "$CON_UUID" )
  case "$IFTYPE" in
  loopback) return;;
  esac
  
  _svc="systemd-timesyncd"
  if test "$( /usr/bin/sysctl is-enabled ${_svc}.service )" = "enabled"; then
    NTPCFGD="/etc/systemd/timesyncd.conf.d"
    mkdir -p "$NTPCFGD"
    test -d "$NTPCFGD" || return
    NTPCFG="${NTPCFGD}/${CON_UUID}.conf"
    RST=0
    case "$MYACTION" in
    down|vpn-down)
      /usr/bin/rm -f "$NTPCFG"
      RST=1
      ;;
    up|vpn-up|dhcp4-change|dhcp6-change)
      _NTP="${DHCP4_NTP_SERVERS} ${DHCP6_NTP_SERVERS}"
      if test -z $_NTP; then
        NCNETCFG="/etc/sysconfig/network/config"
        test -n "$NCNETCFG" -a -r "$NCNETCFG" \
          && source <( \
               /usr/bin/cat "$NCNETCFG" \
                 | /usr/bin/grep "^NETCONFIG_NTP_STATIC_SERVERS=" \
             )
          _NTP="$NETCONFIG_NTP_STATIC_SERVERS"
      fi
      test -z $_NTP && return
      _NTP=$( echo "$_NTP" | /usr/bin/sed -r -e "s/\s+$//" )
      echo "[Time]" >"$NTPCFG"
      echo "NTP=${_NTP}" >>"$NTPCFG"
      RST=1
      ;;
    esac
    test "$RST" -eq 1 -a \
      $( /usr/bin/sysctl is-active ${_svc}.service ) = "active" \
      && /usr/bin/sysctl restart ${_svc}.service &
  fi
} # // end ntp2timesyncd

function nfs_start {
  local target=nfs-client
  local _status=$( /usr/bin/sysctl is-enabled ${target}.target )
  case "$_status" in
  masked*|linked*)
    ;;
  *)
    while read MOUNT_POINT; do
      /usr/bin/mountpoint -q "$MOUNT_POINT" \
        || /usr/bin/mount "$MOUNT_POINT"
    done < <(
      /usr/bin/sed -e '/^.*#/d' -e '/^.*:/!d' -e 's/\t/ /g' /etc/fstab \
        | "/usr/bin/awk" '{ print $2"|"$3 }' \
        | /usr/bin/grep -P "\|(nfs|nfs4)$" \
        | /usr/bin/cut -d'|' -f 1
    )
    "/usr/bin/awk" '{ print $2"|"$3 }' /proc/self/mountinfo \
      | /usr/bin/grep -P "\|(nfs|nfs4)$" \
      | /usr/bin/cut -d'|' -f 1
    ;;
  esac
} # // end nfs_start

function nfs_stop {
  /bin/date
  local target=nfs-client
  /usr/bin/grep -E "\<(nfs|nfs4)\>" /proc/self/mountinfo \
    | "/usr/bin/awk" '{ print $5"|"$9 }' \
    | /usr/bin/grep -P "\|(nfs|nfs4)$" \
    | /usr/bin/cut -d'|' -f 1 \
    | xargs --no-run-if-empty /usr/bin/umount --lazy --force
  /bin/date
} # // end nfs_stop

function syslog_restart {
  local _cfgtype="$1"
  local _svc="syslog-ng"
  if test -n "$_cfgtype"; then
    local _status=$( /usr/bin/sysctl is-enabled ${_svc}.service )
    case "$_status" in
    masked*|linked*)
      ;;
    *)
      local _cfg="/etc/syslog-ng/${_svc}.conf"
      local _cfgn="/etc/syslog-ng/${_svc}-${_cfgtype}.conf"
      if test -e "$_cfgn"; then
        cp "$_cfgn" "$_cfg"
        /usr/bin/sysctl restart ${_svc}.service &
      fi
      ;;
    esac
  fi
} # // end syslog_restart

my_name=$( basename $0 )
LOGPRE="/var/log/${my_name}"
INTERFACE="$1"
ACTION="$2"

test -z "$ACTION" && ACTION="unknown"
test -z "$INTERFACE" && INTERFACE="none"
_LOG=${LOGPRE}-${INTERFACE}-${ACTION}.log
test -e "$_LOG" && mv $_LOG ${_LOG}.old

{
  set -x
  /bin/date
  LANG=C; export LANG
  HOMEURL=http://portal.domain.my/
  MTUVPN=1375
  NFS="yes"
  SYSLOG="yes"
  
  case "$ACTION" in
  pre-up|vpn-pre-up)
    _ACTION="$ACTION"
    if test "$_ACTION" = "pre-up"; then
      IFTYPE=$( iftype_get "$DEVICE_IFACE" )
      test "$IFTYPE" = "wireguard" && _ACTION="vpn-pre-up"
    fi
    case "$_ACTION" in
    vpn-pre-up)
      case "$IFTYPE" in
      wifi)
        test -n "$MTUVPN" \
          && /usr/bin/ip link set "$INTERFACE" mtu "$MTUVPN"
        ;;
      esac
      ;;
    esac
    ;;
  up|vpn-up)
    _ACTION="$ACTION"
    #   a certain kind of vpn
    if test "$_ACTION" = "up"; then
      IFTYPE=$( iftype_get "$DEVICE_IFACE" )
      case "$IFTYPE" in
      wireguard)
        _ACTION="vpn-up"
        test -n "$MTUVPN" \
          && /usr/bin/ip link set "$INTERFACE" mtu "$MTUVPN"
        ;;
      esac
    fi
    ONLINE=""
    test "$_ACTION" = "vpn-up" -o "$IFTYPE" = "ethernet" \
      && ONLINE=$( is_online_with "$HOMEURL" up )
    case "$ONLINE" in
    y|yes|1)
      case "$NFS" in
      y|yes|1) test "$_ACTION" = "up" && nfs_start ;;
      esac
      case "$SYSLOG" in
      y|yes|1) syslog_restart lan ;;
      esac
      ;;
    esac
    ntp2timesyncd "$ACTION" "$CONNECTION_UUID"
    ;;
  pre-down|vpn-pre-down)
    _ACTION="$ACTION"
    if test "$_ACTION" = "pre-down"; then
      IFTYPE=$( iftype_get "$DEVICE_IFACE" )
      test "$IFTYPE" = "wireguard" && _ACTION="vpn-pre-down"
    fi
    case "$_ACTION" in
    pre-down)
      while read xline
      do
        contype=$( echo "$xline" | /usr/bin/cut -d: -f1 )
        case "$contype" in
        vpn|wireguard)
          conid=$( echo "$xline" | /usr/bin/cut -d: -f2 )
          /usr/bin/nmcli connection down uuid "$conid"
          ;;
        esac
      done < <(
        /usr/bin/nmcli --terse --fields "TYPE,UUID" \
                       connection show --active
      )
      ;;
    esac
    if test "$_ACTION" = "vpn-pre-down" -o "$IFTYPE" = "ethernet"; then
      case "$NFS" in
      y|yes|1) nfs_stop ;;
      esac
      case "$SYSLOG" in
      y|yes|1) syslog_restart nolan ;;
      esac
    fi
    ;;
  down|vpn-down)
    _ACTION="$ACTION"
    if test "$_ACTION" = "down"; then
      IFTYPE=$( iftype_get "$DEVICE_IFACE" )
      test "$IFTYPE" = "wireguard" \
        && _ACTION="vpn-down"
    fi
    case "$_ACTION" in
    down)
      ;;
    vpn-down)
      test -n "$MTUVPN" \
        && /usr/bin/ip link set "$INTERFACE" mtu 1500
      ;;
    esac
    ntp2timesyncd "$ACTION" "$CONNECTION_UUID"
    ;;
  esac
  /bin/date
} >"$_LOG" 2>&1

