#!/bin/sh

openvpn_dir="/etc/openvpn"
fliwi_config_base_services='/etc/fliwi/services'
fliwi_config_base_host='/etc/fliwi/host'
reload_openvpn=0
update_host_configs=0
update_services_configs=0
changes_detected=0

##########################
fliwi_script_help()
{
  echo ""
  echo "Update OpenVPN config in Fliwi"
  echo ""
  echo "Usage: $(basename $0) [OPTIONS]"
  echo "====="
  echo ""
  echo "OPTIONS:"
  echo "========"
  echo "--host"
  echo "  Update host based OpenVPN configurations."
  echo ""
  echo "--services"
  echo "  Update service based OpenVPN configurations."
  echo ""
  echo "--restart-openvpn-on-changes"
  echo "  Restart OpenVPN if changes to the config are detected."
  echo ""
}

fliwi_write_config_if_needed()
{
  local my_write_config=0
  local my_etc_openvpn_path="$1"
  local my_config_file="$2"

  if [ ! -f "$my_config_file" ]; then
    echo "ERROR: No file '$my_config_file' present" 1>&2
    return 1
  fi

  if [ ! -d "$(dirname $my_etc_openvpn_path)" ]; then
    echo "ERROR: No firectory '$(dirname $my_etc_openvpn_path)' present" 1>&2
    return 1
  fi

  if [ ! -f "$my_etc_openvpn_path" ] || \
     [ ! -f "$my_etc_openvpn_path.sha1sums" ]; then
    my_write_config=1
  else
    sha1sum -c --status $my_etc_openvpn_path.sha1sums
    if [ $? -ne 0 ]; then
      my_write_config=1
    fi
  fi

  if [ $my_write_config -eq 1 ]; then
    echo "INFO: Updating configuration for '$my_config_file'..." 1>&2
    changes_detected=1
    echo "# Dynamic openvpn(8) configuration generated by $(basename $0)" > $my_etc_openvpn_path
    echo "#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN" >> $my_etc_openvpn_path
    echo "cd $(dirname $my_config_file)" >> $my_etc_openvpn_path
    echo "config $(basename $my_config_file)" >> $my_etc_openvpn_path
    sha1sum $my_config_file $my_etc_openvpn_path > $my_etc_openvpn_path.sha1sums
  fi

  return 0
}



TEMP=$(getopt -o h --long help,host,services,restart-openvpn-on-changes \
              -n "$(basename $0)" -q -- "$@")
if [ $? != 0 ]; then
  fliwi_script_help
  exit 1
fi

eval set -- "$TEMP"

while true
do
  case "$1" in
    -h|--help)
      fliwi_script_help
      exit 1
    ;;

    --host)
      update_host_configs=1
      shift 1
    ;;

    --services)
      update_services_configs=1
      shift 1
    ;;

    --restart-openvpn-on-changes)
      reload_openvpn=1
      shift 1
    ;;

    --)
      shift
      break
    ;;

    *)
      fliwi_script_help
      exit 1
    ;;
  esac
done

if [ $update_host_configs -eq 0 ] && \
   [ $update_services_configs -eq 0 ]; then
  fliwi_script_help
  exit 1
fi

### Removed gone openvpn configs
for etc_openvpn_path in $(find $openvpn_dir -mindepth 1 -maxdepth 1 -type f -path '/etc/openvpn/fliwi-*.conf')
do
  temp_dir_from_config=$(grep -E -e '^cd ' $etc_openvpn_path | cut -d ' ' -f 2)
  temp_name_from_config=$(grep -E -e '^config ' $etc_openvpn_path | cut -d ' ' -f 2)
  temp_path_from_config="$temp_dir_from_config/$temp_name_from_config"

  if [ ! -f "$temp_path_from_config" ]; then
    echo "INFO: Removing obsolete openvpn-linker-config at '$etc_openvpn_path'" 1>&2
    rm -f $etc_openvpn_path
    changes_detected=1
  fi
done


if [ $update_host_configs -eq 1 ]; then
  for config_file in  $(find -L $fliwi_config_base_host -mindepth 3 -maxdepth 3 -type f -path '/etc/fliwi/host/openvpn/config.*/*.conf')
  do
    type="$(echo $config_file | cut --only-delimited -d '/' -f 6 | sed -r 's/^config\.//')"
    config_name="$(echo $config_file | cut --only-delimited -d '/' -f 7)"
    if [ -z "$type" ] || \
       [ -z "$config_name" ]; then
      echo "WARNING: Skipping file '$config_file'" 1>&2
      continue
    fi

    etc_openvpn_name="fliwi-host-$type-$config_name"
    fliwi_write_config_if_needed "$openvpn_dir/$etc_openvpn_name" "$config_file"
  done
fi

if [ $update_services_configs -eq 1 ]; then
  for my_numbered_service in $(fliwi-get-my-services)
  do
    my_service=$(echo $my_numbered_service | sed -r 's/-[0-9]+$//')
    if [ -z "$my_service" ]; then
      continue
    fi

    for config_file in $(find -L $fliwi_config_base_services -mindepth 4 -maxdepth 4 -type f -path '/etc/fliwi/services/'$my_service'/openvpn/config.*/*.conf')
    do
      service_name="$(echo $config_file | cut --only-delimited -d '/' -f 5)"
      type="$(echo $config_file | cut --only-delimited -d '/' -f 7 | sed -r 's/^config\.//')"
      config_name="$(echo $config_file | cut --only-delimited -d '/' -f 8)"

      if [ -z "$service_name" ] || \
         [ -z "$type" ] || \
         [ -z "$config_name" ]; then
        echo "WARNING: Skipping file '$config_file'" 1>&2
        continue
      fi

      etc_openvpn_name="fliwi-service-$service_name-$type-$config_name"
      fliwi_write_config_if_needed "$openvpn_dir/$etc_openvpn_name" "$config_file"
    done
  done
fi

if [ $changes_detected -eq 1 ]; then
  echo "INFO: Changes in configuration detected..." 1>&2
  if [ $reload_openvpn -eq 1 ]; then
    echo "INFO: Restarting openvpn..." 1>&2
    ### Restart openvpn (if running)
    openVpnPID=$(pidof -s openvpn) || openVpnPID=0
    if [ -n "$openVpnPID" ] && \
       [ $openVpnPID -gt 0 ]; then
      if which invoke-rc.d >/dev/null 2>&1; then
        invoke-rc.d openvpn restart || true
      else
        /etc/init.d/openvpn restart || true
      fi
    fi
  fi
else
  echo "INFO: No changes in configuration detected..." 1>&2
fi

exit 0


