#!/bin/bash

# iff executed under VERBOSE=yes provide more information
verbose() {
  if [[ "$VERBOSE" == "yes" ]] ; then
    echo "$*"
  fi
}

# do not rely on hostname(1), might return hostname of the
# deployment system when initially deploying via chroot
if [ -r /etc/hostname ] ; then
  hostname="$(cat /etc/hostname)"

  # on Amazon EC2 /etc/hostname might contain just 'localhost'
  case "$hostname" in
    localhost)
      hostname=$(hostname)
      ;;
  esac
else
  hostname=$(hostname)
fi

if [ -z "${hostname}" ] ; then
  echo "Error: hostname could not be identified." >&2
  exit 1
fi

/etc/init.d/mysql start || true
. /etc/mysql/sipwise.cnf

if [ -z "${SIPWISE_DB_PASSWORD}" ] ; then
  echo 'Error: SIPWISE_DB_PASSWORD is unset (using /etc/mysql/sipwise.cnf).' >&2
  exit 1
fi

# support automated installation
if [ -n "$AUTOMATED_INSTALL_MODE" ] ; then
  echo "Running in automated installation mode, ignoring check for empty db_schema."
else
  if [ "$(mysql -usipwise -p${SIPWISE_DB_PASSWORD} -e 'use ngcp; select * from db_schema;' 2>/dev/null)" = "" ] ; then
    echo "================================================================="
    echo "Warning: the db_schema table of the ngcp database is empty."
    echo "Are you sure you want to proceed with applying db-schema changes?"
    echo "This will DROP and then re-initialize your existing database."
    printf "Please type 'agree' to really continue: "

    unset AGREE
    read AGREE
    if [ "$AGREE" != "agree" ]; then
      echo "Exiting as requested." >&2
      exit 1
    fi
  fi
fi

if ! mysql -usipwise -p${SIPWISE_DB_PASSWORD} -e 'use ngcp;' 2>/dev/null ; then
  mysql -usipwise -p${SIPWISE_DB_PASSWORD} < /usr/share/ngcp-db-schema/db_scripts/init/0005_create_ngcp.up
fi

if ! mysql -usipwise -p${SIPWISE_DB_PASSWORD} -e 'use ngcp;' 2>/dev/null ; then
  echo 'Error: ngcp database does not exist.' >&2
  exit 1
fi

if ! mysql -usipwise -p${SIPWISE_DB_PASSWORD} ngcp -e 'describe db_schema'  >/dev/null; then
  echo 'Error: db_schema table does not exit.' >&2
  exit 1
fi

running_on_active_node() {
  if ! [ -x /usr/sbin/ngcp-check_active ] ; then
    return 1
  else
    if /usr/sbin/ngcp-check_active -q ; then
      verbose "This seems to be the active node, nothing to do."
      return 0
    else
      verbose "This seems to be the inactive node, applying revisions."
      return 1
    fi
  fi
}

apply_revision() {
  [ -n "$1" ] || return 1

  rev="$1"
  revname="$(basename $rev)"

  printf "Applying revision script %s: " "$rev"
  if mysql -usipwise -p${SIPWISE_DB_PASSWORD} < "$rev" ; then
    echo done
  else
    echo "failed. :(" >&2
    echo "Please resolve the problem and run ngcp-update-db-schema again." >&2
    exit 1
  fi

  if mysql -usipwise -p${SIPWISE_DB_PASSWORD} ngcp -e "insert into db_schema values (0, '${revname}', \""${hostname}"\", CURRENT_TIMESTAMP);" ; then
    verbose "Marked revision $rev as applied."
  else
    echo "Error while executing DB commands using revision $rev for host $hostname" >&2
    exit 1
  fi
}

# execute the rev script iff there's no entry for *any* host yet
apply_generic_revs() {
  [ -n "$1" ] || return 1

  rev="$1"
  revname="$(basename $rev)"

  if ngcp-check-rev-applied --schema db_schema --revision "$revname" ; then
    echo "Revision $revname has been applied already, nothing to do."
    return 0
  fi

  apply_revision "$rev"
}

# execute the rev script iff there's no entry for the *current* host yet
apply_host_specific_revs() {
  [ -n "$1" ] || return 1

  rev="$1"
  revname="$(basename $rev)"

  if ngcp-check-rev-applied --schema db_schema --revision "$revname" --node "$hostname" ; then
    echo "Revision $revname has been applied on $hostname already, nothing to do."
    return 0
  fi

  apply_revision "$rev"
}

revision_wrapper() {
  [ -n "$1" ] || return 1

  for rev in $* ; do

    if ! [ -r "$rev" ] ; then
      echo "Error: $rev can not be read." >&2
      exit 1
    fi

    cd $(dirname $rev) || exit 1 # would fail if a script references a file (like language_strings.txt) in its CWD

    revname="$(basename $rev)"

    case "$revname" in
      # the scripts that should be executed on *all* hosts, no matter whether
      # they are active or inactive, since the script's content doesn't get replicated
      *_not_replicated.up)
	apply_host_specific_revs "$rev"
	;;
      *)
	if running_on_active_node ; then
	  echo "Replication script ${revname} noted, nothing to do on active node"
	else
	  apply_generic_revs "$rev"
        fi
	;;
    esac


  done
}

# make sure we get sorted 10XXX after 9XXX
cd /usr/share/ngcp-db-schema/db_scripts/base/
revision_wrapper $(printf '%s\0' *.up | sort -z -n | while IFS= read -r -d "" file; do \
                   echo /usr/share/ngcp-db-schema/db_scripts/base/$file; done)

cd /usr/share/ngcp-db-schema/db_scripts/diff/
revision_wrapper $(printf '%s\0' *.up | sort -z -n | while IFS= read -r -d "" file; do \
                   echo /usr/share/ngcp-db-schema/db_scripts/diff/$file; done)

echo "Synchronizing passwords with MySQL"
ngcp-sync-constants >/dev/null

## END OF FILE #################################################################
