#!/bin/bash

[ ! -z "$SS_CONTROLLER_LIB_UTIL" ] && return 0
SS_CONTROLLER_LIB_UTIL=true
source /etc/openshift/node.conf

function post_start_app () {

    openshift_origin_broker_server=$1

    restart_on_add=${2-false}
    echo "restart_on_add=$restart_on_add"

	if [ -z $OPENSHIFT_SKIP_GIT_HOOKS ]
	then
	    if [ "$OPENSHIFT_CI_TYPE" = "jenkins-1.4" ] && [ -n "$JENKINS_URL" ]
	    then
	        set -e
	        jenkins_build.sh
	        set +e
	    else
	        if [ "$OPENSHIFT_CI_TYPE" = "jenkins-1.4" ]
	        then
	            echo "!!!!!!!!"
	            echo "Jenkins client installed but a Jenkins server does not exist!"
	            echo "You can remove the jenkins client with rhc cartridge remove -a $OPENSHIFT_GEAR_NAME -c jenkins-client-1.4"
	            echo "Continuing with local build/deployment."
	            echo "!!!!!!!!"
	        fi

	        set_app_state building

	        # Do any cleanup before the next build
	        pre_build.sh

	        # Lay down new code, run internal build steps, then user build
	        build.sh

	        set_app_state deploying

	        # Deploy new build, run internal deploy steps, then user deploy
	        deploy.sh

	        hot_deploy_added=false

	        if $restart_on_add ; then

		        while read old_sha1 new_sha1 refname ; do
		          # Detect the addition of the marker
		          if commit_contains_file_with_status "$new_sha1" ".openshift/markers/hot_deploy" "A"; then
		            hot_deploy_added=true
		            break
		          fi
		        done
		    fi

	        echo "hot_deploy_added=${hot_deploy_added}"

	        # Start the app
	        if hot_deploy_marker_is_present && ! $hot_deploy_added ; then
	            echo "App will not be started due to presence of hot_deploy marker"
                    set_app_state started
	        else
	            start_app.sh
	        fi

	        # Run any steps required after startup
	        post_deploy.sh
	    fi

	    # Not running inside a build
	    nurture_app_push.sh $openshift_origin_broker_server
	fi
}

# Stops the app (or not), taking into account the hot_deploy marker.
function pre_stop_app () {

  restart_on_add=${1-false}
  echo "restart_on_add=$restart_on_add"

    # And finally...
  if is_stop_required $restart_on_add; then
    stop_app.sh
  else
    echo "App will not be stopped due to presence of hot_deploy marker"
  fi
}

function is_stop_required () {

  restart_on_add=$1

  # We ONLY want to disable this if the hot deploy marker will be present
  # following the commit application.
  stop_required=true

  # All our decisions will be based on these three states. It is
  # assumed that added/deleted are mutually exclusive states.
  hot_deploy_preexists=false
  hot_deploy_added=false
  hot_deploy_deleted=false


  # Check to see if the marker is already on disk
  if hot_deploy_marker_is_present; then
    hot_deploy_preexists=true
  fi


  # Peek into the inbound push and see if the marker state is being updated
  # in any notable way
  while read old_sha1 new_sha1 refname ; do
    # Detect the addition of the marker
    if commit_contains_file_with_status "$new_sha1" ".openshift/markers/hot_deploy" "A"; then
      hot_deploy_added=true
      break
    fi

    # Detect the deletion of the marker
    if commit_contains_file_with_status "$new_sha1" ".openshift/markers/hot_deploy" "D"; then
      hot_deploy_deleted=true
      break
    fi
  done

  # Debug use
  #echo "hot_deploy_added=${hot_deploy_added}"
  #echo "hot_deploy_deleted=${hot_deploy_deleted}"
  #echo "hot_deploy_preexists=${hot_deploy_preexists}"

  # There are only two cases which should cause the stop to be disabled:
  # 1. The marker is being added and was not present in the first place
  if ! $hot_deploy_preexists && $hot_deploy_added; then
    echo "Will add new hot deploy marker"

    if $restart_on_add ; then
      stop_required=true
    else
      stop_required=false
    fi
  fi

  # 2. The marker is already present and is not modified with this commit
  if $hot_deploy_preexists && ! $hot_deploy_added && ! $hot_deploy_deleted; then
    echo "Existing hot deploy marker will remain unchanged"
    stop_required=false
  fi

  if $stop_required
  then
    return 0
  else
    return 1
  fi
}

# Determines if the given file is present in the given commit with
# the provided status (e.g. add, delete, modified). Returns 0 if
# there is a match, otherwise 1.
function commit_contains_file_with_status () {
  sha1=$1
  filename=$2
  status=$3

  match_present=1

  # compare the diff list filenames with the argument filename
  list=$(git show --pretty="format:" --name-only --diff-filter=[${status}] $sha1)
  for tmpfile in ${list}; do
    if [ "$tmpfile" == "${filename}" ]; then
      match_present=0
      break
    fi
  done

  return $match_present
}

function source_if_exists {
    [ -f "$1" ]  &&  source "$1"
    return 0
}


function get_gear_start_order {
    local start_order=`ls $APP_HOME/{} 2>/dev/null`
    echo $start_order
}

#
# Function to get the start/stop order on the basis of installed carts
# TODO: Replace with reading from start/stop order files when implemented
#
function get_component_order {
    (cd $APP_HOME; ls -dU {10gen-mms-agent-0.1,cron-1.4,jenkins-client-1.4,metrics-0.1,phpmyadmin-3.4,phpmyadmin-3.5,rockmongo-1.1,diy-0.1,jbossas-7,jbosseap-6.0,jbossews-1.0,jbossews-2.0,jenkins-1.4,nodejs-0.6,perl-5.10,perl-5.16,php-5.3,php-5.4,python-2.6,python-2.7,python-3.3,ruby-1.8,ruby-1.9,zend-5.6,haproxy-1.4} 2>/dev/null) | $1
}

# Get the start order from installed carts
function get_start_order {
    echo $(get_component_order "cat")
}

# Get the stop order from installed carts
function get_stop_order {
    echo $(get_component_order "tac")
}

function get_installed_framework_carts {
    local carts
    carts=`(cd $OPENSHIFT_HOMEDIR; ls -d {diy-0.1,jbossas-7,jbosseap-6.0,jbossews-1.0,jbossews-2.0,jenkins-1.4,nodejs-0.6,perl-5.10,perl-5.16,php-5.3,php-5.4,python-2.6,python-2.7,python-3.3,ruby-1.8,ruby-1.9,zend-5.6} 2>/dev/null)`
    echo "${carts[@]}"
}

# Get list of installed databases
function get_installed_databases {
    (cd $OPENSHIFT_HOMEDIR; ls -d {mongodb-2.2,mysql-5.1,postgresql-8.4,postgres-9.1} 2>/dev/null)
}

function get_local_databases {
    dbs=$( (
        cd $CARTRIDGE_BASE_PATH
        for e in $(ls -1 $OPENSHIFT_HOMEDIR/.env/OPENSHIFT_*_DB_URL 2>/dev/null \
                   |sed -e 's/.*OPENSHIFT_\(.*\)_DB_URL/\1/' |tr '[A-Z]' '[a-z]' |sort -u)
        do
          ls -d $e*
        done
    ) )
    echo "${dbs[@]}"
}

# Has a database been attached the this gear?
function get_attached_databases {
    dbs=$( (
        cd $CARTRIDGE_BASE_PATH
        for e in $(ls -1 $OPENSHIFT_HOMEDIR/.env/OPENSHIFT_*_DB_URL $OPENSHIFT_HOMEDIR/.env/.uservars/OPENSHIFT_*_DB_URL 2>/dev/null \
                   |sed -e 's/.*OPENSHIFT_\(.*\)_DB_URL/\1/' |tr '[A-Z]' '[a-z]' |sort -u)
        do
          ls -d $e*
        done
    ) )
    echo "${dbs[@]}"
}

# Public: Start all processes in a given gear
#
# Examples:
#   start_app
#   # => 0
#
# Returns 0 on success
function start_app {
    set_app_state started

    for db in $(get_local_databases)
    do
        run_as_user "${CARTRIDGE_BASE_PATH}/$db/info/bin/app_ctl.sh start" || error "Failed to start ${db}" 121
    done

    for cart in $(get_start_order)
    do
        run_as_user "${CARTRIDGE_BASE_PATH}/$cart/info/bin/app_ctl.sh start" || error "Failed to start ${cart}" 121
    done
}

function stop_app {
    set_app_state stopped

    for cart in $(get_stop_order)
    do
        run_as_user "${CARTRIDGE_BASE_PATH}/$cart/info/bin/app_ctl.sh stop" || error "Failed to stop ${cart}" 121
    done

    for db in $(get_local_databases)
    do
        run_as_user "${CARTRIDGE_BASE_PATH}/$db/info/bin/app_ctl.sh stop" || error "Failed to start ${db}" 121
    done
}

# Start only gear local dbs
function start_dbs {
    for db in $(get_local_databases)
    do
        ${CARTRIDGE_BASE_PATH}/$db/info/bin/app_ctl.sh start || error "Failed to start ${db}" 121
    done
}

# Start all dbs that the current gear can connect to
function start_attached_dbs {
    for db in $(get_attached_databases)
    do
        ${CARTRIDGE_BASE_PATH}/$db/info/bin/app_ctl.sh start || error "Failed to start ${db}" 121
    done
}

function source_if_exists {
    [ -f "$1" ]  &&  source "$1"
    return 0
}

function get_cartridge_instance_dir {
    carttype=${1:-$cartridge_type}
    if [ -n "$carttype" ]; then
        echo "$APP_HOME/$carttype"
    else
        error "${application}. Cartridge type '$carttype' not set." 142
    fi
}

function is_a_scalable_app {
    source /etc/openshift/node.conf
    source_if_exists "${GEAR_BASE_DIR}/$uuid/.env/OPENSHIFT_APP_NAME"

    [ "$application" != "$OPENSHIFT_APP_NAME" ]  &&  return 0
    return 1
}

function create_env_uservars_dir {
    mkdir -p "$APP_HOME/.env/.uservars"
    chmod 755 "$APP_HOME/.env/.uservars"
}

function create_env_uservars_script {
    cat <<EOF > "$APP_HOME/.env/USER_VARS"
#!/bin/bash -e

# Setup user Environment Variables
for f in \$(ls $APP_HOME/.env/.uservars/); do
    n=\$(echo "\$f" | sed 's/[^A-Za-z0-9_]/_/g')
    export \$n=\$(cat "$APP_HOME/.env/.uservars/\$f")
done

EOF

}

# Echo's the value of the given variable name. The
# value is obtained using an eval to allow callers
# an easy way to deal with nested expansion.
function get_env_var_dynamic {
  VAR_NAME=$1
  eval y=\$${VAR_NAME}; echo $y
}


# Infers the current cartridge name from the current
# script directory.
function get_cartridge_name_from_path {
    CART_PATH=$(cd -P $(dirname "$0")/../.. && pwd)
    CART_NAME=$(basename ${CART_PATH})
    echo $CART_NAME
}


# A convenience wrapper which will determine the current
# cartridge name and use that name to derive a cartridge
# namespace value.
function get_cartridge_namespace_from_path {
    CART_NAME=$(get_cartridge_name_from_path)
    CART_NS=$(convert_cart_name_to_namespace_id ${CART_NAME})
    echo $CART_NS
}

# Convert the given cartridge name to env namespace.
function convert_cart_name_to_namespace_id {
    echo $1 | sed 's/-//g' | sed 's/[^a-zA-Z_]*$//g' | tr '[a-z]' '[A-Z]'
}

#
# Get the primary framework ctl script
#
function get_framework_ctl_script() {
    framework_carts=($(get_installed_framework_carts))
    echo ${CARTRIDGE_BASE_PATH}/${framework_carts[0]}/info/bin/app_ctl.sh
}

#
# Tell whether cart is the only cart on a gear
#
function only_cart_on_gear() {
    ret=$(ls ${APP_HOME:-$OPENSHIFT_HOMEDIR}/ | grep -ve "app-root\|git" | grep -v $1 | wc -l)
    return $ret
}

#
# Create cartridge specific variables
#
function create_standard_cart_env_vars {
    CART_NS=$(convert_cart_name_to_namespace_id $cartridge_type)
    cinstancedir=$(get_cartridge_instance_dir)
    echo "export OPENSHIFT_${CART_NS}_LOG_DIR='$cinstancedir/logs/'" > \
                                      $APP_HOME/.env/OPENSHIFT_${CART_NS}_LOG_DIR
}

function create_standard_env_uservars {
    create_env_uservars_dir
    create_env_uservars_script
}

function create_standard_network_env_vars {
    INTERNAL_IP=$1
    INTERNAL_PORT=${2:-8080}
    echo "export OPENSHIFT_INTERNAL_IP='$INTERNAL_IP'" > $APP_HOME/.env/OPENSHIFT_INTERNAL_IP
    echo "export OPENSHIFT_INTERNAL_PORT='$INTERNAL_PORT'" > $APP_HOME/.env/OPENSHIFT_INTERNAL_PORT
}

function create_cart_network_env_vars {
    CART_IP=$1
    CART_PORT=${2:-8080}
    CART_NS=$(convert_cart_name_to_namespace_id $cartridge_type)

    echo "export OPENSHIFT_${CART_NS}_IP='$CART_IP'" > $APP_HOME/.env/OPENSHIFT_${CART_NS}_IP
    echo "export OPENSHIFT_${CART_NS}_PORT='$CART_PORT'" > $APP_HOME/.env/OPENSHIFT_${CART_NS}_PORT
}

function create_standard_repo_dir_env_var {
    # see model/unix_user.rb
    true
}

function create_standard_path_env_var {
    echo "export PATH=$CART_INFO_DIR/bin/:$CARTRIDGE_BASE_PATH/abstract-httpd/info/bin/:$CARTRIDGE_BASE_PATH/abstract/info/bin/:/bin:/usr/bin:/sbin:/usr/sbin" > $APP_HOME/.env/PATH
}

function create_custom_uservars_var {
    echo "$2" > "$APP_HOME/.env/.uservars/$1"
}

#example usage: sed -i $(print_sed_exp_replace_env_var) path/to/file.conf
function print_sed_exp_replace_env_var {
        path_to_env_folder="${OPENSHIFT_HOMEDIR}.env"

        variable_files=`find ${path_to_env_folder} -type f -print`

        sed_exp=""

        for variable_file in $variable_files
        do
                arr_var_file=(`echo $variable_file | tr "/" "\n"`)
                arr_size=${#arr_var_file[@]}
                #use file name as variable name
                variable_name=${arr_var_file[$arr_size - 1]}
                variable_val=(`echo ${!variable_name//\//\\\/}`)

                sed_exp="${sed_exp} -e s/\${env.${variable_name}}/${variable_val}/g"
        done
        printf "%s\n" "$sed_exp"
}

function create_standard_app_dirs {
    mkdir -p run tmp ci
    [ -e repo ] || ln -s ../app-root/repo repo
    [ -e data ] || ln -s ../app-root/data data
    [ -e runtime ] || ln -s ../app-root/runtime runtime
}

function create_cartridge_instance_dir {
    carttype=${1:-$cartridge_type}
    if [ -n "$carttype" ]; then
        mkdir -p "$APP_HOME/$carttype"
    else
        error "${application}. Cartridge type '$carttype' not set." 141
    fi
}

function secure_app_dir {
    # set ownership for all the sub-directories even with dot names to User
    chown -R $user_id.$group_id "$APP_HOME/app-root" || \
        error "Failed to chown new application space." 123

    # reserve ownership of app-root for OpenShift
    chown root.$group_id "$APP_HOME/app-root" || \
        error "Failed to chown new application root." 123

    chown root.root "$APP_DIR"
}

function secure_cart_instance_dir {
    cinstancedir=$(get_cartridge_instance_dir)
    chown $user_id.$group_id -R "$cinstancedir" || \
        error "Failed to chown new application space." 123
    chown root.root "$cinstancedir"
    if [ -f "$cinstancedir/${application}_ctl.sh" ]
    then
      chown root.root "$cinstancedir/${application}_ctl.sh"
    fi
}

function secure_conf_dirs {
    cinstancedir=$(get_cartridge_instance_dir)
    chown root:root -R "$cinstancedir/conf" "$cinstancedir/conf.d"
}

function check_cartridge_dir_doesnt_exist {
    if [ -d "$APP_HOME/$cartridge_type" ]; then
        error "${application}. Cartridge directory $APP_HOME/$cartridge_type already exists." 132
    fi
}

function check_app_dir_exists {
    if [ ! -d "$APP_HOME/app-root" ]
    then
        error "${application}.  Application directory doesn't exist:  $APP_HOME/app-root" 125
    fi
}

function rm_cartridge_instance_dir {
    ctype=${1:-$cartridge_type}
    [ -n "$ctype" ]  &&  runcon -l s0-s0:c0.c1023 rm -rf "$APP_HOME/$ctype"
}

function load_resource_limits_conf {
    if [ -f '/etc/openshift/resource_limits.conf' ]
    then
        . /etc/openshift/resource_limits.conf
    fi
}

function generate_password {
    head -n 50 /dev/urandom|tr -dc "a-np-zA-NP-Z1-9-_"|fold -w 12 | grep -v '^-' | head -n1
}

function generate_username {
    if [ "$1" ]
    then
        username="$1"
    else
        username="admin"
    fi

    remain=$(( 12 - ${#username} ))
    if [ "$remain" -ge 1 ]
    then
        rnstr=$(head -n 50 /dev/urandom|tr -dc "a-np-zA-NP-Z1-9"|fold -w $remain | head -n1)
        username="${username}${rnstr}"
    fi
    echo $username
}

function error {
    echo "$1" 1>&2
    exit "$2"
}

function warning {
    echo "$1" 1>&2
    #echo "$2"
}

function client_result {
    echo "CLIENT_RESULT: $1"
}

function client_message {
    echo "CLIENT_MESSAGE: $1"
}

function client_error {
    echo "CLIENT_ERROR: $1"
}

function client_internal_error {
    echo "CLIENT_INTERNAL_ERROR: $1"
}

function client_debug {
    echo "CLIENT_DEBUG: $1"
}

function set_app_info {
    echo "APP_INFO: $1"
}

function send_attr {
    echo "ATTR: $1"
}

function add_ssh_key {
    echo "SSH_KEY_ADD: $1"
}

function add_app_ssh_key {
    echo "APP_SSH_KEY_ADD: $1 $2"
}

function add_env_var {
    echo "ENV_VAR_ADD: $1"
}

function app_remove_env_var {
    echo "APP_ENV_VAR_REMOVE: $1"
}

function add_broker_auth_key {
    echo "BROKER_AUTH_KEY_ADD: "
}

function remove_broker_auth_key {
    echo "BROKER_AUTH_KEY_REMOVE: "
}

function cart_data {
    echo "CART_DATA: $@"
}

function cart_props {
    echo "CART_PROPERTIES: $@"
}

function setup_configure {
    source ${CARTRIDGE_BASE_PATH}/abstract/info/lib/git
    source ${CARTRIDGE_BASE_PATH}/abstract/info/lib/network
    source ${CARTRIDGE_BASE_PATH}/abstract/info/lib/apache

    CART_INFO_DIR=$CARTRIDGE_BASE_PATH/$cartridge_type/info
    CART_CONF_DIR=$CART_INFO_DIR/configuration/etc/conf

    load_resource_limits_conf

    application="$1"
    namespace=`basename $2`
    uuid=$3
    git_url=$4

    setup_app_dir_vars
    setup_user_vars

    #
    # Get user id info
    # Not caching this information caused some early chowns to work but some later
    # chowns to fail with a user not found error
    user_id=$(id -u "$uuid") || error "Could not find user $uuid ($namespace)" 134
    group_id=$(id -g "$uuid") || error "Could not find user $uuid ($namespace)" 135
}

function setup_deconfigure {
    source ${CARTRIDGE_BASE_PATH}/abstract/info/lib/git
    source ${CARTRIDGE_BASE_PATH}/abstract/info/lib/network
    source ${CARTRIDGE_BASE_PATH}/abstract/info/lib/apache

    CART_INFO_DIR=$CARTRIDGE_BASE_PATH/$cartridge_type/info

    namespace=`basename $2`
    application="$1"
    uuid=$3

    setup_app_dir_vars
    setup_user_vars
}

function setup_embedded_configure {
    source ${CARTRIDGE_BASE_PATH}/abstract/info/lib/network
    source ${CARTRIDGE_BASE_PATH}/abstract/info/lib/apache

    CART_INFO_DIR=$CARTRIDGE_BASE_PATH/embedded/$cartridge_type/info
    CART_ETC_DIR=$CART_INFO_DIR/configuration/etc
    CART_CONF_DIR=$CART_INFO_DIR/configuration/etc/conf

    load_resource_limits_conf

    application="$1"
    namespace=$2
    uuid=$3

    setup_basic_vars

    user_id=$(id -u "$uuid") || error "Could not find user $uuid" 134
    group_id=$(id -g "$uuid") || error "Could not find user $uuid" 135
}

function setup_embedded_deconfigure {
    source ${CARTRIDGE_BASE_PATH}/abstract/info/lib/network
    source ${CARTRIDGE_BASE_PATH}/abstract/info/lib/apache

    CART_INFO_DIR=$CARTRIDGE_BASE_PATH/embedded/$cartridge_type/info

    application="$1"
    namespace=$2
    uuid=$3

    setup_basic_vars
}

function setup_basic_hook {
    uuid=`basename $3`
    namespace="$2"
    application="$1"
    setup_basic_vars
}

function setup_basic_vars {
    setup_app_dir_vars
    check_app_dir_exists
    setup_user_vars
}

function setup_app_dir_vars {
    APP_HOME="$GEAR_BASE_DIR/$uuid/"
    OPENSHIFT_HOMEDIR="$APP_HOME"
    APP_DIR=`echo $APP_HOME/$cartridge_type | tr -s /`
    APP_REPO_DIR="$APP_HOME/app-root/repo"
    APP_DATA_DIR="$APP_HOME/app-root/data"

    export APP_HOME OPENSHIFT_HOMEDIR
}

function force_kill {
    pid=$1
    for i in {1..12}
    do
        if ! /bin/kill -0 $pid > /dev/null 2>&1
        then
            echo "Waiting for stop to finish"
            sleep .2
            if [ $i -gt 9 ]
            then
                /bin/kill -9 $pid
            fi
        else
            break
        fi
    done
}

function confirm_log_files_inactive {
    log_dir="$1"
    for LOGFILE in `find $log_dir -type f`
    do
      for PID in `/usr/sbin/lsof -t $LOGFILE`
      do
        /bin/kill -9 $PID
      done
    done
}

function confirm_pid_gone {
    pid_file="$1"
    i=0
    while [ -f $pid_file ] && [ $i -lt 30 ]
    do
        sleep .2
        i=$(($i + 1))
    done
}

function wait_for_stop {
	pid=$1
    for i in {1..60}
    do
        if `ps --pid $pid > /dev/null 2>&1`
        then
            echo "Waiting for stop to finish"
            sleep .5
        else
            break
        fi
    done
}

function import_env_vars {
    for f in $APP_HOME/.env/*
    do
        . $f
    done
}

function translate_env_vars {
  source_if_exists $OPENSHIFT_HOMEDIR/.env/TYPELESS_TRANSLATED_VARS
  xlations=( $(echo $TRANSLATE_GEAR_VARS) )
  i=0
  while [ "${xlations[$i]}" ]
  do
    keyname="${xlations[$i]}"
    i=$(( $i + 1 ))
    valref="${xlations[$i]}"
    i=$(( $i + 1 ))
    keyprev=$(eval "echo \$$keyname")
    if [ "$keyname" ] && [ "$valref" ] && [ -z "$keyprev" ]
    then
      eval "export ${keyname}=\"\$${valref}\""
    fi
  done
}

function print_all_running_processes {
    echo ""
    echo "Running Processes:"
    echo ""
    ps -eFCvx
    echo ""
}

function print_user_running_processes {
    myuserid=$1
    echo ""
    echo "Running Processes:"
    echo ""
    ps -FCvx -U "${myuserid}"
    echo ""
}

function status_client_result {
    output=$1
    IFS_BAK=$IFS
IFS="
"
    for line in $output
    do
        client_result "$line"
    done
    IFS=$IFS_BAK
}

function observe_setup_app_and_git_dirs {
    observe_setup_var_lib_dir "$APP_HOME/git/"
    observe_setup_var_lib_dir "$APP_HOME/app-root/"
    observe_setup_var_lib_dir "$APP_DIR"
}

function observe_setup_cart_instance_dir {
    observe_setup_var_lib_dir "$(get_cartridge_instance_dir)"
}

function observe_setup_env_uservars_dir {
    observe_setup_var_lib_dir "$APP_HOME/.env/.uservars"
}

function setup_user_vars {
    uid=$(id -u "$uuid")
    mcs_level=`oo-get-mcs-level $uid`
    export mcs_level
}

function observe_setup_app_home {
    PATH=$PATH:/usr/sbin:/sbin restorecon -R $APP_HOME
}

function observe_setup_var_lib_dir {
    if [ -e "$1" ]
    then
        PATH=$PATH:/usr/sbin:/sbin restorecon -R $1
        chcon -l $mcs_level -R $1
    else
        warning "The dir does not exist: $1"
    fi
}

function observe_setup_var_lib_file {
    if [ -e "$1" ]
    then
        PATH=$PATH:/usr/sbin:/sbin restorecon $1
        chcon -l $mcs_level $1
    else
        warning "The file does not exist: $1"
    fi
}


function run_as_user {
    _uuid=${uuid:-$OPENSHIFT_GEAR_UUID}
    (
        if [ -d "$APP_HOME" ]
        then
            cd "$APP_HOME"
        fi
        if [ "`whoami`" = "$_uuid" ]; then
        #  Run confined as user - temporary bandaid to fix issues with
        #  ss-connector-execute - connection hooks are run unconfined.
            if [ "$(runcon | cut -f 3 -d ':')" != "openshift_t" ]; then
                runcon -r system_r -t openshift_t -l $mcs_level $@
            else
                eval "$1"
            fi
        else
            PATH=$PATH:/usr/sbin:/sbin runuser --shell /bin/sh "$_uuid" -c "runcon -r system_r -t openshift_t -l $mcs_level $1"
        fi
    )
}


function super_run_as_user {
    (
        if [ -d "$APP_HOME" ]
        then
            cd "$APP_HOME"
        fi
        /bin/su -s /bin/sh "$uuid" -c "runcon -r system_r -t openshift_t -l $mcs_level $1"
    )
}



function daemon_as_user {
    (
        if [ -d "$APP_HOME" ]
        then
            cd "$APP_HOME"
        fi
        daemon --user="$uuid" runcon -r system_r -t openshift_t -l $mcs_level "$@"
    )
}

function validate_run_as_user {
    uuid=$OPENSHIFT_GEAR_UUID
    setup_user_vars

    if whoami | grep -q root || ! runcon | grep system_r:openshift_t:$mcs_level > /dev/null
    then
        echo 1>&2
        echo "Current context: " `runcon` 1>&2
        echo 1>&2
        echo "Please run script in the correct context, try:" 1>&2
        echo "run_as_user \"<command>\"" 1>&2
        echo 2>&1
        exit 15
    fi
}

function openshift_state_dir {
  echo "${APP_HOME:-$OPENSHIFT_HOMEDIR}/app-root/runtime"
}

function get_app_state {
  get_cartridge_state `openshift_state_dir`
}

function get_cartridge_state {
  _state_file="$1/.state"
  if [ -f "$_state_file" ]; then
    cat "$_state_file"
  else
    echo unknown
  fi
}

# expected values: building, deploying, started, idle, new, stopped, or unknown
function set_app_state {
  set_cartridge_state `openshift_state_dir` $1
}

function set_cartridge_state {
  _state=`get_cartridge_state "$1"`

  if [ ! \( "idle" = "$_state" -a "stopped" = "$2" \) ]; then
    _state_file="$1/.state"
    rm -f "$_state_file"
    echo "$2" > "$_state_file"
    chown --reference="$1" "$_state_file"
    chcon --reference="$1" "$_state_file"
    chmod 640 "$_state_file"
  fi
}

function test_app_state {
  _state=`get_app_state`
  return `test "$_state" = "$1"`
}

function test_cartridge_state {
  _state=`get_cartridge_state "$1"`
  return `test "$_state" = $2`
}

function src_user_hook {
    # Run pre_start, pre_stop, post_start, post_stop hooks.
    # The pre_* hooks may modify environment.
    local hook="${OPENSHIFT_REPO_DIR}.openshift/action_hooks/$1"
    shift

    if [ $(id -u) -eq 0 ]; then
        echo "ERROR: src_user_hook called as root" 1>&2
        exit 15
    fi

    if [ -f "$hook" ]; then
        source "$hook" "$@"
    fi
}


function run_user_hook {
    # Run pre_start, pre_stop, post_start, post_stop hooks.
    # The pre_* hooks may modify environment.
    local hook="${OPENSHIFT_REPO_DIR}.openshift/action_hooks/$1"
    shift

    if [ $(id -u) -eq 0 ]; then
        echo "ERROR: run_user_hook called as root" 1>&2
        exit 15
    fi

    if [ -f "$hook" ]; then
        "$hook" "$@"
    fi
}

function enable_cgroups {
    if [ $ENABLE_CGROUPS -eq 1 ]; then
      cgset -r cpu.cfs_quota_us=$cfs_quota /openshift/$uuid
    fi
}

function disable_cgroups {
    if [ $ENABLE_CGROUPS -eq 1 ]; then
      export cfs_quota=$(cgget -n -v -r cpu.cfs_quota_us /openshift/${uuid})
      cfs_period=$(cgget -n -v -r cpu.cfs_period_us /openshift/${uuid})
      cgset -r cpu.cfs_quota_us=${cfs_period} /openshift/${uuid}
    fi
}

function enable_stale_detection {
    rm -f "${APP_HOME:-$OPENSHIFT_HOMEDIR}/.disable_stale"
}

function  disable_stale_detection {
    touch "${APP_HOME:-$OPENSHIFT_HOMEDIR}/.disable_stale"
}

# In practice, this function is only invoked asynchronously, with no defined
# way of dealing with the hook output. Letting the streams flow back to the
# parent process is unreliable if the hook outlives the parent. There is no
# consistent place to store the output on disk. Until these issues are
# addressed, redirect the standard streams to /dev/null.
function resolve_application_dependencies {
    uuid=$1
    application=$2

    for env_var in ${GEAR_BASE_DIR}/${uuid}/.env/*
    do
        . $env_var
    done

    pushd "${GEAR_BASE_DIR}/${uuid}/git/$application.git"
    super_run_as_user "${GEAR_BASE_DIR}/${uuid}/git/$application.git/hooks/pre-receive &> /dev/null"
    super_run_as_user "${GEAR_BASE_DIR}/${uuid}/git/$application.git/hooks/post-receive &> /dev/null"
    popd
}

# Checks for the presence of the user-specified hot_deploy marker in the app
# repo. Returns 0 if the marker is present, otherwise 1.
function hot_deploy_marker_is_present {
  if [ -f "${OPENSHIFT_REPO_DIR}/.openshift/markers/hot_deploy" ]; then
    return 0
  else
    return 1
  fi
}

# Checks for the CI_BUILD variable. Returns 0 if the variable is not empty,
# otherwise 1. This is used to provide scripts with information about the
# build context (e.g., are we currently executing in a Jenkins build).
function in_ci_build {
  if [ -z "$CI_BUILD" ]; then
    return 1
  else
    return 0
  fi
}

if [ -f /usr/libexec/openshift/lib/util_ext ]
then
    source /usr/libexec/openshift/lib/util_ext
fi
# DON'T PUT ANYTHING BELOW UTIL_EXT CHECK
