#!/bin/bash
#---------------------------------------------------------------------
##
## @Libgrimoire
##
## @Synopsis Set of functions containing the spell writing API.
##
##
## These functions can be used in the PRE_BUILD, BUILD, POST_BUILD
## and POST_INSTALL sections of spells.
##
## @Copyright
## Original version Copyright 2001 by Kyle Sallee
## Additions/Corrections Copyright 2002 by the Source Mage Team
##
#---------------------------------------------------------------------

#---------------------------------------------------------------------
## @Type API
## @param directory name 
## @param [size]
## Creates a tmpfs filesystem.  By default, the size is 1GB.
## The caller may optionally supply a size argument.
## <pre>
## Example1:  Create a 2GB mount at $SOURCE_DIRECTORY
##
##    mk_source_dir  $SOURCE_DIRECTORY  2g
##
## Example2:  Create a mount at /tmp/newdir, defaults to 1GB size
##
##    mk_source_dir  /tmp/newdir
## </pre>
#---------------------------------------------------------------------
function real_mk_source_dir() {

  debug  "libgrimoire" "Running mk_source_dir() on $SOURCE_DIRECTORY"

  local NEW_DIR=$1
  local NEW_DIR=${NEW_DIR:=$SOURCE_DIRECTORY}

  local SIZE=$2
  local SIZE=${SIZE:=1g}

  if  [  -n  "$NEW_DIR"  ];  then

    rm_source_dir  $NEW_DIR
    mkdir     $NEW_DIR  &&
    if  [[  $TMPFS == on  ]]; then
      mount  -o  size=$SIZE,nr_inodes=1m  -t  tmpfs  tmpfs  $NEW_DIR
    fi
  fi

}


#---------------------------------------------------------------------
## @param  [directory to remove]
## @Globals SOURCE_DIRECTORY
## Removes the given directory or SOURCE_DIRECTORY if no argument is
## given.
##
#---------------------------------------------------------------------
function real_rm_source_dir() {

  DEAD_DIR=$1
  DEAD_DIR=${DEAD_DIR:-$SOURCE_DIRECTORY}

  debug  "libgrimoire" "Running rm_source_dir() on $DEAD_DIR"

  if  [  -n  "$DEAD_DIR"  ] &&  [  -d  "$DEAD_DIR"  ];  then

    pushd $BUILD_DIRECTORY 2>&1  >  /dev/null

    umount  -l  $DEAD_DIR  2>  /dev/null

    # We don't really want to use "rm -rf", but if not using tmpfs,
    # we have to. So we move the old dir to a known place before
    # running rm. This prevents accidental damage that could be
    # caused by
    # a) $DEAD_DIR being an empty string
    # b) $DEAD_DIR being set to "/" (or anything above /usr/src)
    # c) $DEAD_DIR containing metacharacters (like newline)
    mv  "$DEAD_DIR"  "$INSTALL_ROOT/usr/src/deaddir"  &&
    rm  -rf          "$INSTALL_ROOT/usr/src/deaddir"  2>  /dev/null

    popd  2>&1  >  /dev/null
    true

  fi

}


#---------------------------------------------------------------------
##
## Override calls to the make program. Used to add custom arguments and
## handle failures when using multiple jobs.
##
#---------------------------------------------------------------------
function make() {

  local JOBS=""

  local make_njobs=${MAKE_NJOBS:-1}
  local jobs_per_host=${JOBS_PER_HOST:-0}
  local tmp num_hosts=0
  for tmp in $DISTCC_HOSTS; do let num_hosts+=1; done
  local JOBS

  # if the parent didnt define this, define it here
  if [[ ! "$REAL_MAKE" ]] ; then
    local REAL_MAKE
    find_make REAL_MAKE || return $?
  fi


  if [[ "$USE_DISTCC" == on ]] ; then
    let JOBS=$(($make_njobs+$jobs_per_host*$num_hosts))
  else
    let JOBS=$make_njobs
  fi

  if  [[ $JOBS == 0 ]]; then
    # Zero jobs has the effect of unlimiting the number of make processes
    JOBS=""
  else
    # Check there is a reasonable value.
    [ $JOBS -lt 0 ] ||
    echo $JOBS|grep -q '[0-9]+' &&
    JOBS="1" # Use default of one when MAKE_NJOBS is nonsense.
  fi

  debug  "libgrimoire"  "make: running with $JOBS jobs"
  $REAL_MAKE -j $JOBS -S "$@"

  # Cache the result
  local  STATUS=$?

  if [[ $STATUS -ne 0 ]] && [[ "$JOBS" != 1 ]] ; then
    query "Running make with $JOBS jobs failed. Attempt to run with a single job?" y &&
    # Try again
    $REAL_MAKE -j1 -S "$@"
    STATUS=$?
  fi

  # Return the exit status
  return $STATUS

}

#---------------------------------------------------------------------
## Install files in a spells "desktop" subdirectory for .desktop
## @param Spell 
## @Stdout file name
#---------------------------------------------------------------------
function install_desktop_files() { 
  debug "libgrimoire" "Running install_desktop_files() on $SPELL"
  local each file
  local target_dir="/usr/share/applications"
  local desktop_dir="$SCRIPT_DIRECTORY/desktop"
  test -d $desktop_dir || return 0

  mkdir -p $target_dir
  for each in $(find $desktop_dir -maxdepth 1 -type f); do
    file=$(basename $each)
    if ! test -f "$target_dir/$file" ; then
      debug "libgrimoire" "Installing $file in $target_dir as a desktop file"
      cp $each $target_dir
    fi
  done
}


#---------------------------------------------------------------------
## @Type API
## @param spell
## Returns the current version of the given spell
##
#---------------------------------------------------------------------
function real_installed_version()  {

  local spell="$1"

  grep "^$spell:"  $SPELL_STATUS  |  cut  -d : -f4  |  head  -n 1

}


#---------------------------------------------------------------------
## @param spell
## @param default answer to dispel query
## @Type API
## If the default answer is anything other than 'y' then 'n' is assumed.
## returns the given spellname if it is installed
##
#---------------------------------------------------------------------
function real_conflicts() {

  debug  "libgrimoire" "Running conflicts() on $1. Default query answer $2."

  if  spell_installed  $1;  then
    [  "$2"  =  y  ]  &&  echo  "$1:y"  ||  echo  "$1:n"
  fi

  true

}


#---------------------------------------------------------------------
## @Stdout Warning messages.
## Provides a neatly formatted rejection dialog for the
## various rejected spells that might require user warnings.
## See ask_continue_with_rejected for second part of this function.
##
#---------------------------------------------------------------------
function warn_rejected()
{
  message "${MESSAGE_COLOR}This spell is considered${PROBLEM_COLOR}" \
          "rejected${DEFAULT_COLOR}${MESSAGE_COLOR} because of the"   \
          "following reason:\n"
  message "${PROBLEM_COLOR}$REJECT${DEFAULT_COLOR}${MESSAGE_COLOR}.\n"
  message "Please view the software website for more information:\n"
  message "${DEFAULT_COLOR}$WEB_SITE${MESSAGE_COLOR}\n"
  message "You may continue casting the spell and it will still be tracked" \
          "by Sorcery.\nHowever, the software installation process may have" \
          "questions that need to be\nanswered and/or licensing agreements" \
          "that must be agreed to.${DEFAULT_COLOR}\n"
}


#---------------------------------------------------------------------
## @Stdout Question
## @Stdin  Answer ;-)
## Part two of the warn_rejected funtion, ask if user wants to continue
## anyway. (defaults to NO), unless running in UNATTEND_SAFE mode.
##
#---------------------------------------------------------------------
function ask_continue_with_rejected()
{
  if spell_installed "$SPELL" && [ -e $SCRIPT_DIRECTORY/UNATTEND_SAFE ]; then
    message "${SPELL_COLOR}$SPELL${DEFAULT_COLOR}${MESSAGE_COLOR} is" \
            "installed, and has been determined" \
            "to be ${FILE_COLOR}safe\nfor unattended" \
            "update${DEFAULT_COLOR}${MESSAGE_COLOR}, so the prompt will" \
            "be skipped.${DEFAULT_COLOR}\n"
    return
  fi
  message "\n${MESSAGE_COLOR}Allowing the next question to timeout will" \
          "choose not to install this spell.\nThis means that rejected" \
          "spells ${PROBLEM_COLOR}will not be installed or updated" \
          "automatically.\n"
  message "${DEFAULT_COLOR}${MESSAGE_COLOR}If you want a rejected spell to" \
          "be installed or updated you must\nconfirm your decision now or" \
          "cast the spell later.${DEFAULT_COLOR}\n"
  if ! query  "CONTINUE casting?" n; then
    return 1
  fi
  message "\n${MESSAGE_COLOR}OK, here we go... you are on your" \
          "own!${DEFAULT_COLOR}"
}


#---------------------------------------------------------------------
## @License
##
## This software is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This software is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this software; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
##
#---------------------------------------------------------------------
