#---------------------------------------------------------------------
##
##=head1 SYNOPSIS
##
## Functions for dealing with the actual compiling/installation of spells
## and walking through casts 'pass 4' pipeline.
##
##=head1 DESCRIPTION
##
##
##=head1 COPYRIGHT
##
## Copyright (C) 2002 The Source Mage Team <http://www.sourcemage.org>
##
##=head1 FUNCTIONS
#---------------------------------------------------------------------

#---------------------------------------------------------------------
## Prompts the user about possible security problems with the current
## spell. Allows a safe way of failing a spell due to security problems.
## @return 0 if there are no security problem or the user acknowledges them.
## @return 1 if the user decides not to accept the security concerns
#---------------------------------------------------------------------
# checks for a security file
# returns 0 if spell should be cast, 1 otherwise
function run_security() {
    debug "build_api/common" "Starting run_security() on $SPELL"
    if    [  -f  $SCRIPT_DIRECTORY/SECURITY  ]; then
      echo -e "${SPELL_COLOR}${SPELL}:${DEFAULT_COLOR}"
      tee -a $SECURITY_LOG < $SCRIPT_DIRECTORY/SECURITY
        if [ `grep critical $SCRIPT_DIRECTORY/SECURITY` ]; then
          if query "${RED}SECURITY CRITICAL:${QUERY_COLOR} Do you still want to cast ${SPELL_COLOR}${SPELL}${DEFAULT_COLOR}?" "n"; then
            return 0
          fi
          return 1
        else
          if query "SECURITY: Do you still want to cast ${SPELL_COLOR} $SPELL ${QUERY_COLOR}?" "y"; then
            return 0
          fi
          return 1
        fi
    fi
    return 0
}


#---------------------------------------------------------------------
## pokes around for a configure or src/configure and if it exists
## asks the user if they want to edit the custom options
#---------------------------------------------------------------------
function run_config_loc () {
  debug "build_api/common" "Starting run_config_loc() on $SPELL"
  pushd . > /dev/null # may have been somewhere else
  [  -d  "$SOURCE_DIRECTORY"  ]  &&
  cd      $SOURCE_DIRECTORY   # we need to be in here for this function to work
  if  [[  $CONFIG_LOC  == on  ]]; then

    if  [ -x ./configure ] || [ -x ./src/configure ] ; then

      if  [  !  -d  $SM_CONFIG_OPTION_CACHE  ] ; then
        mkdir --parents --mode=0755 $SM_CONFIG_OPTION_CACHE
      fi

      if  [  -f $SM_CONFIG_OPTION_CACHE/$SPELL  ] ; then
        message "${MESSAGE_COLOR}These are your current -- config options for spell ${SPELL_COLOR}$SPELL"
        message "${FILE_COLOR}($SM_CONFIG_OPTION_CACHE/$SPELL)"
        cat $SM_CONFIG_OPTION_CACHE/$SPELL | column
      fi

      if    query  "Do you wish to add -- options to ./configure?"  n ;  then
	F_TMP=$TMP_DIR/cast.$$.configure
        rm -f $F_TMP
				
        if [ -x ./configure ]; then
          ./configure --help > $F_TMP
        elif [ -x ./src/configure ]; then
          ./src/configure --help > $F_TMP
        fi

        if [ -f $F_TMP ]; then
          sedit 's/^/# /' $F_TMP
        fi

        cat $SM_CONFIG_OPTION_CACHE/$SPELL >> $F_TMP 2>/dev/null
        edit_file $F_TMP
        rm -f $SM_CONFIG_OPTION_CACHE/$SPELL
        sedit '/^#.*$/d' $F_TMP
        mv $F_TMP $SM_CONFIG_OPTION_CACHE/$SPELL
      fi

      # load custom OPTS
      if  [  -f $SM_CONFIG_OPTION_CACHE/$SPELL  ];  then
        OPTS="$OPTS $(< $SM_CONFIG_OPTION_CACHE/$SPELL)"
        message "${MESSAGE_COLOR} OPTS= ${DEFAULT_COLOR}$OPTS"
      fi

    fi

  fi

  popd &>/dev/null

}

#---------------------------------------------------------------------
## @Type API
## Prepares to install the spell.  If the spell is installed already,
## the libraries are saved with save_libraries() and the spell is dispelled.
## Usually called from the BUILD or PRE_INSTALL script of a spell.
## Locks "libgrimoire" "install" before proceeding.
## If the spell is not installed (or held) the spell is not dispelled.
##
#---------------------------------------------------------------------
function real_prepare_install() { (

  debug  "libgrimoire" "Running prepare_install() on $SPELL"

  message  "${MESSAGE_COLOR}Preparing to install"  \
           "${SPELL_COLOR}${SPELL}${DEFAULT_COLOR}"

  devoke_installwatch
  lock_resources "libgrimoire" "install"

    if  spell_installed  $SPELL   ||
        spell_held       $SPELL
    then

      trap  "spell_recover"  SIGINT
      save_libraries
      dispel  --notriggers --nosustain  $SPELL

    fi
) }

#---------------------------------------------------------------------
##
## Gathers all documentation files from source archive and installs
## them as part of the spell
##
#---------------------------------------------------------------------
function real_gather_docs()  {

  if  [  "$GATHER_DOCS"  ==  "on"  ]; then

    debug  "libgrimoire" "Running gather_docs() on $SPELL DOCS=$DOCS"

    DOC_DIR=$DOCUMENT_DIRECTORY/$SPELL
    mkdir  -p  $DOC_DIR

    for i in ${DOCS[@]}
    do
      cp -r $SOURCE_DIRECTORY/${i} $DOC_DIR 2>/dev/null
    done

    # what is this here for and why isn't it part of the standard DOCS
    # variable?
    cp $SOURCE_DIRECTORY/*rc $DOC_DIR 2>/dev/null

    # making installed docs readable for all users.
    chmod -fR a+r $DOC_DIR

  fi

}


#---------------------------------------------------------------------
##
## Copies pam configuration files to /etc/pam.d/
##
#---------------------------------------------------------------------
function install_pam_confs()  {

  debug  "libgrimoire" "Running install_pam_confs() on $SPELL"

  if  [  -d  "$SCRIPT_DIRECTORY/pam.d"  ];  then
    cd       "$SCRIPT_DIRECTORY/pam.d"

    mkdir  -p  $INSTALL_ROOT/etc/pam.d
    local FILE
    for  FILE  in  `ls`;  do
      if  !  [  -f  $INSTALL_ROOT/etc/pam.d/$FILE  ];  then
        cp  $FILE   $INSTALL_ROOT/etc/pam.d
      fi
    done

  fi

}

#---------------------------------------------------------------------
## Stuff that should be done if run_build_spell succeeds
## This is intended to be overridable at some point
#---------------------------------------------------------------------
function run_spell_success() {
    debug "build_api/common" "cast of $SPELL-$VERSION was successful"

    local INST_LOG="$INSTALL_LOGS/$SPELL-$VERSION"
    local MD5_LOG="$MD5SUM_LOGS/$SPELL-$VERSION"
    local TMP_INST_LOG="$TMP_DIR/$SPELL-$VERSION.install"
    local TMP_MD5_LOG="$TMP_DIR/$SPELL-$VERSION.md5"
    local CACHE="$INSTALL_CACHE/$SPELL-$VERSION-$HOST.tar"
    local CACHE_COMP=${CACHE}${EXTENSION}
    local C_LOG_COMP="$COMPILE_LOGS/$SPELL-$VERSION$EXTENSION"

    sound  SUCCESS

    # announce to everyone the spell succeeded
    activity_log  "cast"  "$SPELL"  "$VERSION"  "success"
    add_spell $SPELL installed $VERSION
    echo $SPELL >> $SUCCESS_LIST

    # update depends info
    debug "build_api/common" "Merging depends info"
    local t_DEPENDS_STATUS=$(lock_start_transaction $DEPENDS_STATUS)
    # none of the old values are valid, only the new, uncommitted values are
    remove_depends_status $t_DEPENDS_STATUS $SPELL
    local spell_depends=$(hash_get uncommitted_hash $SPELL)
    if [ -e $spell_depends ] ; then
      cat  $spell_depends >> $t_DEPENDS_STATUS
    fi
    lock_commit_transaction $DEPENDS_STATUS

    # since the database is now accurate, no reason to keep old answers
    # floating around
    test -e "$ABANDONED_DEPENDS/$SPELL" &&
    rm -f $ABANDONED_DEPENDS/$SPELL &>/dev/null

    # compile log
    create_compile_log
    view_compile_log

    local tablet_dir=$(tablet_get_path $SPELL)
    if [ "$?" != 0 ] ; then
      message "failed to make a tablet directory: $tablet_dir" \
              "this may be a bug"
      unset tablet_dir
    else
      message  "${MESSAGE_COLOR}Creating tablet in directory"        \
               "${FILE_COLOR}${tablet_dir}${DEFAULT_COLOR}"
      tablet_install_spell_files $tablet_dir

      # this data is now doubly stale, remove it
      rm  -f $ABANDONED_PERSIST/$SPELL.p
    fi

    # install log
    message  "${MESSAGE_COLOR}Creating install log" \
             "${FILE_COLOR}${INST_LOG}${DEFAULT_COLOR}"
    # this will make a "root" format install log it will need to be
    # reformatted to "log" format (see log_adjuster in libtrack for details)
    # but basically replacing INSTALL_ROOT with TRACK_ROOT
    create_install_log $IW_LOG $TMP_INST_LOG
    if [[ $tablet_dir ]] ; then
      find $tablet_dir >> $TMP_INST_LOG
    fi
    log_adjuster $TMP_INST_LOG $INST_LOG root log

    # md5sum log
    message  "${MESSAGE_COLOR}Creating MD5 log"        \
             "${FILE_COLOR}${MD5_LOG}${DEFAULT_COLOR}"
    create_md5list $TMP_INST_LOG $TMP_MD5_LOG
    log_adjuster $TMP_MD5_LOG $MD5_LOG root log md5_log_filter

    # do this before cache archive creation (bug 8249)
    rm_source_dir

    # cache archive

    # Archives are stored with INSTALL_ROOT and STATE_ROOT stripped.
    # this way they can be unpacked anywhere and sorcery will know
    # where things will be.
    create_cache_archive $TMP_INST_LOG $CACHE $CACHE_COMP

    report_install
    rm  -f $IW_LOG $C_LOG $TMP_INST_LOG $TMP_MD5_LOG $spell_depends
}

#---------------------------------------------------------------------
## Stuff that should be done if run_build_spell fails
## This is intended to be overridable at some point
#---------------------------------------------------------------------
function run_spell_failure() {
    debug "build_api/common" "cast of $SPELL-$VERSION failed"
    local rc=$1

    sound  FAILURE

    activity_log "cast" "$SPELL"  "$VERSION" "failure"
    echo $SPELL >> $FAILED_LIST

    # if it failed after PRE_BUILD make a compile log
    if [ "$rc" != 1 ] ; then
      create_compile_log
      view_compile_log
    fi

    # put the answers somewhere where they can still be used later
    mkdir -p $ABANDONED_DEPENDS
    local spell_depends=$(hash_get uncommitted_hash $SPELL)
    [ -e $spell_depends ] && mv $spell_depends $ABANDONED_DEPENDS/$SPELL

    # This may have been locked if there was a failure during the install
    unlock_resources "libgrimoire" "install"

    IW_LOG="$INSTALLWATCHFILE"
    devoke_installwatch

    rm -f $IW_LOG $C_LOG

    [[  $CLEAN_SOURCE == on ]] && rm_source_dir
    CAST_EXIT_STATUS=1
}
