#---------------------------------------------------------------------
## @Synopsis Functions for dealing with the actual compiling/installation of spells and walking through casts 'pass 4' pipeline.
## @Copyright Copyright (C) 2002 The Source Mage Team &lt;http://www.sourcemage.org&gt;
## @Globals $SGL_LIBRARY_MODULES $GRIMOIRE $BUILD_API $USE_FUNCTIONS
## A spell follows the following path during its installation:
## PREPARE -&gt; DETAILS -&gt; PRE_BUILD -&gt; BUILD, or COMPILE/INSTALL -&gt;
## POST_BUILD -&gt; POST_INSTALL -&gt; TRIGGERS
## Each of these steps, along with some interim steps of dealing with
## conflicts and security are handled here as well.
#---------------------------------------------------------------------

#---------------------------------------------------------------------
## This is used to dynamically setup an api environment for a spell
## into the build api that it is specified to use. (ie split BUILD or
## no split BUILD).
#---------------------------------------------------------------------
function load_build_api() {

  debug "libcast" "Starting load_build_api"

  source $SGL_LIBRARY_MODULES/build_api/common
  case $BUILD_API in
    1) source $SGL_LIBRARY_MODULES/build_api/api1 ;;
    2) source $SGL_LIBRARY_MODULES/build_api/api2 ;;
    *) message "${PROBLEM_COLOR}Unknown build api version $BUILD_API, for" \
               "$SPELL!!${DEFAULT_COLOR}"
       message "Please update sorcery and see if the problem goes away."
       message "If it doesnt this may be a bug, please contact" \
               "the sorcery team. Thanks."
       return 1 ;;
  esac

  # the following allows spell writers to override certain functions
  # in the build pipeline
  USE_FUNCTIONS=${USE_FUNCTIONS:-on}
  if [[ $USE_FUNCTIONS == "on" ]] ; then
    [ -x $GRIMOIRE/FUNCTIONS ] && . $GRIMOIRE/FUNCTIONS
    [ -x $SECTION_DIRECTORY/FUNCTIONS ] && . $SECTION_DIRECTORY/FUNCTIONS
  elif [[ $USE_FUNCTIONS == "grimoire" ]] ; then
    [ -x $GRIMOIRE/FUNCTIONS ] && . $GRIMOIRE/FUNCTIONS
  elif [[ $USE_FUNCTIONS == "section" ]] ; then
    [ -x $SECTION_DIRECTORY/FUNCTIONS ] && . $SECTION_DIRECTORY/FUNCTIONS
  fi
  return 0
}


#---------------------------------------------------------------------
## Loads up this environment with the special configuration values
## that the spell needs. Typically the mode of communication between
## CONFIGURE/DEPENDS to PRE_BUILD, BUILD, COMPILE, INSTALL, etc.
## @Globals $SPELL_CONFIG $DEPENDS_CONFIG
#---------------------------------------------------------------------
function prepare_spell_config()  {

  SPELL_CONFIG=$DEPENDS_CONFIG/$SPELL
  if  !  [  -x  $SPELL_CONFIG  ];  then
    touch       $SPELL_CONFIG
    chmod  a+x  $SPELL_CONFIG
  fi

  . $SPELL_CONFIG

}

#---------------------------------------------------------------------
## Prompts the user if they want to invoke the services in
## SCRIPT_DIRECTORY/xinetd.d/* via xinetd.
## An optional depends is set on or off depending on whether or not
## the user wants to invoke a spell via xinetd
#---------------------------------------------------------------------
function use_xinetd()  {
  local SERVICES SERVICE ALL_SERVICES SERVICES_DISABLE
  debug "cast" "In use_xinetd()"
  
  if  [  -d  $SCRIPT_DIRECTORY/xinetd.d  ]  &&
      !  grep  -q  "SERVICES="  $SPELL_CONFIG
  then

    debug "cast" "use_xinetd: found an xinetd directory - processing"
    ALL_SERVICES=`cat  $SCRIPT_DIRECTORY/xinetd.d/*  |
                  grep  "service"                    |
                  sed   "s/service //"`
                  
    debug "cast" "use_xinetd: ALL_SERVICES: '$ALL_SERVICES'"

    # only looking for services to install, non-selected services
    # will be installed and disabled in install_xinetd_confs().
    for  SERVICE  in  $ALL_SERVICES;  do
      if    query  "Invoke $SERVICE via xinetd?"  y
      then 
        SERVICES="$SERVICE $SERVICES"
      else
        SERVICES_DISABLE="$SERVICE $SERVICES_DISABLE" 
      fi
    done

    debug "cast" "use_xinetd: to install SERVICES: '$SERVICES'"
    debug "cast" "use_xinetd: to disable SERVICES_DISABLE: '$SERVICES_DISABLE'"
    debug "cast" "setting up depends for services"

    if    [  -n  "$SERVICES"  ] ; then 
      private_common_depends "xinetd" "on" "optional" "" ""
    else
      private_common_depends "xinetd" "off" "optional" "" ""
    fi

    echo  "SERVICES=\"$SERVICES\""  >>  $SPELL_CONFIG
    echo  "SERVICES_DISABLE=\"$SERVICES_DISABLE\""  >> $SPELL_CONFIG

  fi

}

#---------------------------------------------------------------------
## Installs the services selected from use_xinetd
#---------------------------------------------------------------------
function install_xinetd() { (
  if  [  -d  $SCRIPT_DIRECTORY/xinetd.d  ] ; then
    mkdir  -p  /etc/xinetd.d
    SERVICES=""          # services to be installed.
    SERVICES_DISABLE=""  # services not to install.
    . $SPELL_CONFIG
    pushd "$SCRIPT_DIRECTORY/xinetd.d" >/dev/null

    # install and enable
    for  FILE in  $SERVICES;  do
      cp  $FILE  /etc/xinetd.d
      chmod +x  /etc/xinetd.d/$FILE  
    done

    # install but disable
    for  FILE in  $SERVICES_DISABLE;  do
      cp  $FILE  /etc/xinetd.d
      chmod -x  /etc/xinetd.d/$FILE  
    done
    popd >/dev/null
  fi
) }

#---------------------------------------------------------------------
## Prompts the user if they want the init.d scripts the current spell
## has to be installed.
#---------------------------------------------------------------------
# Automagic initscript installation.
function use_initd()  { (

  debug "cast" "In use_initd()"

  INITDSCRIPTS=""
  INITDSCRIPTS_DISABLED=""

  if  [  -d  $SCRIPT_DIRECTORY/init.d  ]  ; then
    debug "cast" "use_initd: found an init.d directory - processing"

    . $SPELL_CONFIG

    local ALL_INITSCRIPTS=`find "$SCRIPT_DIRECTORY/init.d/" -type f -not -name "*.conf" -printf '%f '`
    debug "cast" "use_initd: ALL_INITSCRIPTS: '$ALL_INITSCRIPTS'"

    local INITSCRIPT
    for  INITSCRIPT in $ALL_INITSCRIPTS  ;  do

      echo  "$INITDSCRIPTS $INITDSCRIPTS_DISABLED"  |  \
          grep  -Eq  "( |^)$INITSCRIPT( |$)"  &&  continue

      local default_answer=n
      grep -Fq 'ESSENTIAL=yes' "$SCRIPT_DIRECTORY/init.d/$INITSCRIPT" && default_answer=y
      if  query  "Invoke $INITSCRIPT at boot via init?"  $default_answer  ;  then
        INITDSCRIPTS="$INITSCRIPT $INITDSCRIPTS"
        init_prepare_install  $INITSCRIPT
      else
        INITDSCRIPTS_DISABLED="$INITSCRIPT $INITDSCRIPTS_DISABLED"
      fi
    done
  fi
    
  tmp=$(  grep  -v  -e '^INITDSCRIPTS='  -e '^INITDSCRIPTS_DISABLED='  \
      $SPELL_CONFIG )
  echo "$tmp" > $SPELL_CONFIG
  echo  "INITDSCRIPTS=\"$INITDSCRIPTS\""  >>  $SPELL_CONFIG
  echo  "INITDSCRIPTS_DISABLED=\"$INITDSCRIPTS_DISABLED\"" >> $SPELL_CONFIG
) }

#---------------------------------------------------------------------
## Copies any init.d files from the SCRIPT_DIRECTORY to the /etc/init.d.
## Hopefully saving the old one if it exists and only setting the
## executable bit if the user specified that the init.d script should be
## started at bootup.
#---------------------------------------------------------------------
function install_initd() { (
    debug "cast" "install_initd: to install INITDSCRIPTS: '$INITDSCRIPTS'"
    debug "cast" "install_initd: to disable INITDSCRIPTS_DISABLED: '$INITDSCRIPTS_DISABLED'"
    debug "cast" "saving initscripts"
    
    INITDSCRIPTS=""
    INITDSCRIPTS_DISABLED=""
    . $SPELL_CONFIG

#    local ALL_INITSCRIPTS=`ls  $SCRIPT_DIRECTORY/init.d/ | grep  -v  '\.conf$'`
    # now we install the selected scripts.
    if  [  -n  "$INITDSCRIPTS"  ] ; then
      debug "cast" "install_initd: about to call install_initd_confs"
      install_initd_confs enabled $INITDSCRIPTS
    fi

    # and disable the others.
    if  [  -n  "$INITDSCRIPTS_DISABLED"  ] ; then
      debug "cast" "install_initd: about to disable : '$INITDSCRIPTS_DISABLED'"
      install_initd_confs disabled $INITDSCRIPTS_DISABLED
    fi
    
) }


#---------------------------------------------------------------------
## Takes the compile log and stuffs it into
## our compile log directory.
#---------------------------------------------------------------------
function create_compile_log()  {

  message  "${MESSAGE_COLOR}Creating compile log"                  \
           "${FILE_COLOR}$COMPILE_LOGS/$SPELL-$VERSION$EXTENSION"  \
           "${DEFAULT_COLOR}"

  if [  -z  "$EXTENSION"  ];  then
    cp  $C_LOG  $COMPILE_LOGS/$SPELL-$VERSION
  else
    $COMPRESSBIN  -f  <  $C_LOG  >  $COMPILE_LOGS/$SPELL-$VERSION$EXTENSION
  fi
}


#---------------------------------------------------------------------
## Prompts the user to view the compile log
## and deletes the temporary files too
#---------------------------------------------------------------------
function view_compile_log()  {

    debug "libcast" "In view_compile_log, C_LOG=$C_LOG"
    report $C_LOG  "Compile log"
}


#---------------------------------------------------------------------
## @param spellname
## calls run_details and returns the returnvalue of
## [ -f $INSTALL_CACHE/$SPELL-$VERSION-$BUILD.tar.bz2 ]
#---------------------------------------------------------------------
function can_resurect()  {
	debug "libcast" "can_resurect - $*"
	run_details		&&
	[ -f $INSTALL_CACHE/$SPELL-$VERSION-$BUILD.tar$EXTENSION ] &&
	debug "cast" "I am able to resurect."
}

function resurrect()  {  (  

  debug "libcast" "resurrect - $*"

  can_resurect
#  run_details  run by can_resurect now

  # needed because of build splitification
  load_build_api || return 1

  STATUS=installed

  if  spell_held  $SPELL;  then
    VERSION=`installed_version  $SPELL`
     STATUS=held
    dispel --notriggers $SPELL
  fi

  CACHE_COMP="$INSTALL_CACHE/$SPELL-$VERSION-$BUILD.tar$EXTENSION"
  CONTINUE=false

  if    [  !              -f  $CACHE_COMP   ];  then
    false
  elif  [                 -z  "$EXTENSION"  ];  then
    if  $COMPRESSBIN  -tf  $CACHE_COMP  1>/dev/null
    then
      CONTINUE=true;
    fi
  elif  $COMPRESSBIN  -tf  $CACHE_COMP
  then
    CONTINUE=true;
  fi

  if  $CONTINUE
  then
    run_conflicts    &&
    # can this please go away?
    satisfy_depends  &&

    # new tarballs are cached relative to $INSTALL_ROOT
    pushd $INSTALL_ROOT/ &>/dev/null
    if  [  -n  "$EXTENSION"  ];  then
      $COMPRESSBIN   -cd   $CACHE_COMP  |  tar  -Pkx  1>/dev/null  2>&1
    else
      tar  -Pkxf  $CACHE_COMP  1>/dev/null  2>&1
    fi 
    popd &>/dev/null

    # minor hack until I re-write this (afk 4/12/2004)
    if [ $BUILD_API == 2 ] ; then
      run_final
    else
      run_post_install 
    fi
    run_triggers
    
    add_spell     "$SPELL"  "$STATUS"  "$VERSION"
    pop_install_queue "$SPELL"
    activity_log  "cast"  "$SPELL"  "$VERSION"  "success"
    clear_line
    message  "${RESURRECT_COLOR}Resurrected spell:"  \
             "${SPELL_COLOR}${SPELL}"                \
             "${DEFAULT_COLOR}"                      \
             "version"                               \
             "${VERSION_COLOR}${VERSION}"            \
             "${DEFAULT_COLOR}"
    cleanse --fix  $SILENT  $SPELL && echo $SPELL >> $SUCCESS_LIST
  else
    echo $SPELL >> $FAILED_LIST
    false
  fi

  # run ldconfig 
	message "${MESSAGE_COLOR}Updating the shared libraries ...${DEFAULT_COLOR}"
  release_saved_libraries

)  }


#---------------------------------------------------------------------
## LC means "line count" why not just type line_count?
## @TODO This function is dumb. It should be fixed.
## @param download log file name
#---------------------------------------------------------------------
function show_download_progress()  {

  local download_log=$1
  if  [  -f  "$download_log"   ]   &&
      [  -z  "$SILENT"  ];  then

    LC_OLD=${LC_OLD:-0}

    LC=`cat  $download_log  2>/dev/null  |  wc  -l  |  tr  -d ' '`

    if  [  "$LC"  !=  "$LC_OLD"  ];  then
      ((  LC_OLD++  ))
      sed  -n ${LC_OLD},${LC}p  $download_log
      LC_OLD=$LC
    fi

  fi

}

#---------------------------------------------------------------------
## Shows download progress. Waits for the download to start, and shows
## the progress until the download is done.
## Pawn most of the display out to <@function show_download_progress>
## @TODO fix the old style ad-hoc IPC
## @param Spell to show the download progress for
#---------------------------------------------------------------------
function show_downloading()  {

  local SPELL=$1
  local download_log=$(get_spell_dl_log $SPELL)
  debug "cast" "Started show_downloading() on $SPELL from $download_log"

  # poke around waiting for downloading to start
  while ! ( [[ $download_log ]] && 
            [  -f "$download_log"  ] ) 
  do
    sleep 1
  done

  # isn't this out of band ipc great?
  until [  -f "${download_log}.done"  ] ;  do
    show_download_progress $download_log
    sleep 1
  done
  
  show_download_progress $download_log
  debug "libcast" "Out of show_downloading"
}


#---------------------------------------------------------------------
## Report that something got installed, and possibly display the report
## Pawns the work off to <@function var.lib.sorcery.modules.libsorcery,report>
## @Globals INST_LOG
#---------------------------------------------------------------------
function report_install()  {

  debug "libcast" "In report_install, INST_LOG=$INST_LOG"
  report  $INST_LOG  "Install log"

}

#---------------------------------------------------------------------
## Gets the filename of the download log file
## @param Spell 
## @Stdout file name
#---------------------------------------------------------------------
function get_spell_dl_log() {
  echo "$TMP_DIR/download.$1"
}

#---------------------------------------------------------------------
## @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
##
#---------------------------------------------------------------------
