#!/bin/bash

PHOTON_VERSION=`( cat /etc/photon-release | grep -i "vmware photon" ) | cut -d- -f1 | grep -o -E '[0-9]+.[0-9]+'`
LATEST_VERSION='2.0'


deprecated_pkgs=('consul-template' 'fleet' 'nomad' 'rocket' 'NetworkManager' 'NetworkManager-devel' 'vault')

#some packages like fleet, rocket etc are removed from 2.0
#lets remove those before moving to 2.0
function remove_unsupported_pkgs() {
  for pkg in ${deprecated_pkgs[@]}; do
    pkgremove=`rpm -q $pkg`
    if [ $? -eq 0 ]; then
      tdnf erase $pkg -y
      if [ $? -ne 0 ]; then
        echo "Could not erase $pkg. Cannot continue."
        exit
      fi
    fi
  done
}

#move mesos-devel along
function fix_mesos_devel_symlink() {
  has_mesos_devel=`rpm -q mesos-devel`
  if [ $? -eq 0 ]; then
    if [ -d '/usr/include/mesos/slave' ] && [ ! -L '/usr/include/mesos/slave' ] && [ ! -d '/usr/include/mesos/agent' ]; then
      mv /usr/include/mesos/slave /usr/include/mesos/agent
      ln -s /usr/include/mesos/agent /usr/include/mesos/slave
    fi
  fi
}

#there are certain packages that cause upgrade issues.
#upgrade those to latest within the current version
#so that they dont cause a problem in distro-sync
function fix_packages_with_upgrade_issues() {
  pkgs=('httpd:2.4.25-3.ph1'
        'lldb:3.9.1-3.ph1'
        'libevent:2.0.22-4.ph1'
        'netcat:0.7.1-3.ph1'
        'nfs-utils:1.3.3-5.ph1'
        'nginx:1.11.13-3.ph1'
        'pciutils:3.3.1-3.ph1'
        'userspace-rcu:0.9.1-3.ph1'
        'texinfo:6.1-3.ph1')
  for pkg in ${pkgs[@]}; do
    name=${pkg%%:*}
    version=${pkg#*:}
    current_version=`rpm -q --queryformat %{version}-%{release} $name`
    if [ $? -eq 0 ]; then
      if [[ "$version" > "$current_version" ]]; then
        echo "updating $name to version $version or higher."
        tdnf update -qy "$name"
        if [ $? -ne 0 ]; then
          echo "Could not update $1 to version $2 or higher. Cannot continue"
          exit
        fi
        current_version=`rpm -q --queryformat %{version}-%{release} $name`
        if [[ "$version" > "$current_version" ]]; then
          echo "Could not update $name to version $version or higher. Cannot continue"
          exit
        fi
      fi
    fi
  done
  fix_mesos_devel_symlink
}

function upgrade_photon_release() {
   tdnf -y update photon-release --releasever=$LATEST_VERSION --refresh
}

function distro_upgrade() {
   tdnf distro-sync --refresh
}

function rebuilddb() {
   rpm --rebuilddb
}

#must reboot after an upgrade
function ask_for_reboot() {
  read -p "Reboot is recommended after an upgrade. Reboot now(y/n)?" yn
  case $yn in
    [Yy]* ) reboot;;
    [Nn]* ) exit;;
  esac
}

#if the current install has packages deprecated in the target version,
#there is no clean upgrade path. confirm if it is okay to remove.
function check_deprecated() {
  pkgs_to_remove=''
  for pkg in ${deprecated_pkgs[@]}; do
    installed=`rpm -q $pkg`
    if [ $? -eq 0 ]; then
      pkgs_to_remove="${pkgs_to_remove}${pkg}\n"
    fi
  done
  if [ "$pkgs_to_remove" != "" ];then
    echo "The following packages are deprecated and must be removed before upgrade."
    echo -e $pkgs_to_remove
    read -p "Proceed(y/n)?" yn
    case $yn in
      [Nn]* ) exit;;
    esac
  fi
}

#there is a chance that /var/run is a directory
#in this case, move its contents to /run and make it a symlink
function make_var_run_a_symlink() {
  if [ -d '/var/run' ] && [ ! -L '/var/run' ] ; then
    mv /var/run/* /run
    rm -rf /var/run
    ln -sf /run /var/run
  fi
}

#next version of photon uses specs with dependencies
#of the form x or y. update tdnf, libsolv and rpm to support it.
function update_solv_to_support_complex_deps() {
   tdnf -y update libsolv rpm tdnf --refresh
   rebuilddb
}

function check_and_upgrade() {
  if [ $PHOTON_VERSION == $LATEST_VERSION ]; then
    echo "Your current version $PHOTON_VERSION is the latest version. Nothing to do."
    exit
  fi
  check_deprecated
  echo "You are about to upgrade PhotonOS from $PHOTON_VERSION to $LATEST_VERSION."
  echo -n "Please backup your data before proceeding. Continue (y/n)?"
  read
  echo

  case $REPLY in
    [Yy]*)
      update_solv_to_support_complex_deps
      remove_unsupported_pkgs
      fix_packages_with_upgrade_issues
      rebuilddb
      make_var_run_a_symlink
      upgrade_photon_release
      distro_upgrade
      rebuilddb
      ask_for_reboot
      ;;
    *) exit;;
  esac
}

check_and_upgrade