#!/bin/bash

arch="amd64"
os=linux
INTERNAL_NIC="eth0"
version=${vecm_version}
ftp_addr=100.100.100.101:80
veen_cloud_dir="/usr/local/vecloud"
veen_cloud_monitor_dir=/var/log/vecloud-monitor
veen_cloud_monitor_log=$veen_cloud_monitor_dir/vecloud_monitor.log

## tools
timestamp(){
 date +"%Y-%m-%d %T"
}

is_error(){
  if [ $? -ne 0 ]; then
      out_error cmd error: $*
  fi
}

out_error(){
  echo -e "$(timestamp)" "\033[31m ERROR >> $* \033[0m"
  echo -e "$(timestamp)" "\033[31m ERROR >> $* \033[0m" >> $veen_cloud_monitor_log
  exit -1
}

out_success(){
  echo -e "$(timestamp)" "\033[32m $* \033[0m"
  echo -e "$(timestamp)" "\033[32m $* \033[0m" >> $veen_cloud_monitor_log
}

out_warn(){
  echo -e "$(timestamp)" "\033[33m WARN >> $* \033[0m"
  echo -e "$(timestamp)" "\033[33m WARN >> $* \033[0m" >> $veen_cloud_monitor_log
}

out_logs(){
  echo -e "$(timestamp)" "\033[33m INFO >> $* \033[0m" >> $veen_cloud_monitor_log
}

## check
check_os(){
  case `uname -s` in
    Linux)
      os="linux"
      ;;
    *)
      out_error "Unsupported OS: $(uname -s)"
      ;;
  esac
}

check_os_version(){
  osId="$(. /etc/os-release && echo "$ID")"
  osVersion="$(. /etc/os-release && echo "$VERSION_ID")"
  osArch="$( lscpu  | grep Architecture | awk '{printf $2}')"
  if [[ "$osArch" != "x86_64" ]] &&
     [[ "$osArch" != "aarch64" ]]; then
        out_warn "OS Architecture $osArch has not support!"
  fi

  if [[ "$osArch" == "x86_64" ]]; then
      arch="amd64"
  elif [[ "$osArch" == "aarch64" ]]; then
      arch="arm64"
  fi

  case $osId in
  centos)
     if [[ "$osVersion" != 7* ]] && [[ "$osVersion" != 8* ]]; then
        out_warn OS $os Version $osVersion has not been tested and may not succeed!
     fi
     ;;
  ubuntu)
     if [[ ! "$osVersion" =~ ^(16.04|18.04|20.04|22.04)$ ]]; then
        out_warn OS $osId Version $osVersion has not been tested and may not succeed!
     fi
     ;;
  debian)
     if [[ "$osVersion" != 9* ]]  && [[ "$osVersion" != 10* ]]; then
        out_warn OS $osId Version $osVersion has not been tested and may not succeed!
     fi
     ;;
  *| '')
     out_warn OS $osId has not been tested and may not succeed!
     ;;
esac
}

## Check internal network interfaces
get_master_internal_nic() {
  NIC_NAMES=$(ip -o link show | sort | awk -F': ' '$2 !~ /lo|-primary|-standby/ {print $2}')
  CLOUD_INIT_NETWORK=$(cloud-init query ds.network_json.links)

  for NIC_NAME in $NIC_NAMES; do
    IP_LIST=$(ip -4 -o addr show $NIC_NAME | awk '/inet /{print $4}')
    MAC_ADDR=$(ip link show $NIC_NAME | awk '/ether/ {print $2}')
    if [[ -z "$IP_LIST" ]]; then
      continue
    fi

    is_internal_nic=true
    for IP in $IP_LIST; do
      if [[ $IP =~ ^10\.|^172\.(1[6-9]|2[0-9]|3[0-1])\.|^192\.168\. ]]; then
        continue
      else
        is_internal_nic=false
        break
      fi
    done

    if [[ $is_internal_nic == true ]]; then
      if echo "$CLOUD_INIT_NETWORK" | grep -q $MAC_ADDR; then
        INTERNAL_NIC=$NIC_NAME
        return
      fi
    fi
  done
}

check_push_metrics(){
  get_master_internal_nic
  ip route add 100.100.100.96/27 dev $INTERNAL_NIC
  wget ${ftp_addr}/vecloud_monitor_linux.sh -O /tmp/vecloud_monitor_linux.sh -t 3 --connect-timeout=2
  if [ $? -eq 0 ]; then
      return 0
  fi

  ## transfer data by gateway
  next_gateway=$(ip route show 10.0.0.0/8 dev $INTERNAL_NIC | awk '/via/ {print $3}')
  if [ ! -z $next_gateway ]; then
      ip route del 100.100.100.96/27 dev $INTERNAL_NIC
      ip route add 100.100.100.96/27 dev $INTERNAL_NIC via $next_gateway
      wget ${ftp_addr}/vecloud_monitor_linux.sh -O /tmp/vecloud_monitor_linux.sh -t 3 --connect-timeout=2
      if [ $? -ne 0 ]; then
          out_error "The machine not support push metrics!"
      fi
  fi
}

check(){
  init
  check_os
  check_os_version
  check_push_metrics
  out_success ">> Check install vecloud-monitor finish! <<"
}

## install
init(){
  ulimit -v unlimited ## Avoid system without write file permissions
  if [[ -z "${version}" ]]; then
      version=latest
  fi
  mkdir -p /var/log/vecloud-monitor/
  echo "$(date)" start init vecloud-monitor >> $veen_cloud_monitor_log
}

download(){
  rm -rf $veen_cloud_dir/vecloud-monitor
  mkdir -p $veen_cloud_dir
  echo ${ftp_addr}/vecloud-monitor-$os-$arch-$version.tar.gz
  wget ${ftp_addr}/vecloud-monitor-$os-$arch-$version.tar.gz -O $veen_cloud_dir/vecloud-monitor-$os-$arch-$version.tar.gz -t 3 --connect-timeout=2
  is_error "download vecloud-monitor-$os-$arch-$version.tar.gz error"
  tar -xzvf $veen_cloud_dir/vecloud-monitor-$os-$arch-$version.tar.gz -C $veen_cloud_dir/ && rm -rf $veen_cloud_dir/vecloud-monitor-$os-$arch-$version.tar.gz
  chmod +x $veen_cloud_dir/vecloud-monitor/vecloud-monitor
  echo -n "Running vecloud-monitor infos: "
  $veen_cloud_dir/vecloud-monitor/vecloud-monitor --version
}

install_cloud-monitor(){
  cat << EOF > /etc/systemd/system/vecloud-monitor.service
  [Unit]
  Description=vecloud-monitor
  After=network.target
  After=cloud-final.service

  [Service]
  CPUQuota=20%
  MemoryMax=200M
  MemoryLimit=200M
  LimitNOFILE=100
  ExecStartPre=/bin/mkdir -p /var/log/vecloud-monitor/
  ExecStartPre=/bin/bash /usr/local/vecloud/vecloud-monitor/script/config_route.sh
  ExecStart=/usr/local/vecloud/vecloud-monitor/vecloud-monitor \
    --monitor.interval=30 \
    --log.level=info \
    --log.path=/var/log/vecloud-monitor/vecloud_monitor.log
  Restart=always
  RestartSec=5

  [Install]
  WantedBy=default.target
EOF

  systemctl daemon-reload
  systemctl restart vecloud-monitor.service
  systemctl enable vecloud-monitor.service
}

check_install_succeed(){
  runtimeStatus="$(systemctl status vecloud-monitor.service | grep Active |  awk '{print $3}')"
  if [[ $runtimeStatus == "(running)" ]]; then
     out_success ">> Install vecloud-monitor succeed! <<"
  else
     out_error ">> Install vecloud-monitor failed! <<"
  fi
}

install(){
  check
  init
  download
  install_cloud-monitor
  check_install_succeed
}

## uninstall
uninstall(){
  systemctl stop vecloud-monitor.service
  systemctl disable vecloud-monitor.service
  rm -rf /etc/systemd/system/vecloud-monitor.service
  rm -rf $veen_cloud_dir/vecloud-monitor/
  systemctl daemon-reload
  out_success ">> Uninstall vecloud-monitor succeed! <<"
  rm -rf $veen_cloud_monitor_dir
}

## help
help_global(){
echo '
Usage:
  ./vecloud_monitor_linux.sh command [flags]

Available Commands:
  check        Check whether install vecloud_monitor for linux machine
  install      Install vecloud_monitor to linux machine
  uninstall    Uninstall vecloud_monitor from linux machine
Flags:
  -h, --help   Help for vecloud_monitor_linux.sh
'
}

help(){
  case $1 in
  check | install | uninstall |''| *)
     help_global
     exit 0
     ;;
esac
}


## main
main(){
  case $1 in
  check)
      if [ -n "$2" ]; then
         help
         return 0
      fi
      check
      return 0
      ;;
  install)
     if [[ -n "$2" ]] && [[ "$2" == "-h" ]]; then
        help
        return 0
     fi
     install $*
     return 0
     ;;
  uninstall)
     if [ -n "$2" ]; then
        help
        return 0
     fi
     uninstall
     return 0
     ;;
  help | -h | --h | -help | --help | *)
     help $2
     exit 0
     ;;
esac
}

main $*
