#!/bin/bash

# directly process all given information as a single command
# 1 = command to execute
tkis_execute(){
  if [[ $1 == "" ]] ; then
    error "tkis_execute(): command name not supplied while trying to process $color_reset$color_notice$rule_name$color_reset$color_error on line #$color_reset$color_notice$current$color_reset$color_error with $color_reset$color_notice$tkis_process$color_reset$color_error for $color_reset$color_notice$program_name"
  fi

  if [[ $1 != "" && $(echo $1 | grep -s "^#") == "" ]] ; then
    # make sure the bash command will not do something dangerous
    tkis_security_check $1
    tkis_deny_private_variables $1

    # make tighten the security around the rm command
    if [[ $(echo $1 | grep -s "^[[:space:]]*rm ") != "" ]] ; then
      tkis_security_check_remove $(echo $1 | sed -e 's|^[ ]*rm ||' -e 's|--[::alnum::]*||g' -e 's|-[::alnum::]*||g')

      if [[ $tkis_running_on_host == "yes" ]] ; then
        tkis_security_check_host_remove $(echo $1 | sed -e 's|^[ ]*rm ||' -e 's|--[::alnum::]*||g' -e 's|-[::alnum::]*||g')
      fi

      echoit $1
      eval $1

      if ! [ $? -eq 0 ] ; then
        error "tkis_execute(): failed to execute: \"$color_reset${color_notice}$1$color_reset$color_error\" in rule $color_reset$color_notice$rule_name$color_reset$color_error on line #$color_reset$color_notice$current$color_reset$color_error with $color_reset$color_notice$program_name$color_reset$color_error for $color_reset$color_notice$tkis_process"
      fi
    else
      echoit $1
      eval $1

      if ! [ $? -eq 0 ] ; then
        error "tkis_execute(): failed to execute: \"$color_reset$color_notice$1$color_reset$color_error\" in rule $color_reset$color_notice$rule_name$color_reset$color_error on line #$color_reset$color_notice$current$color_reset$color_error with $color_reset$color_notice$program_name$color_reset$color_error for $color_reset$color_notice$tkis_process"
      fi
    fi
  fi
}

# 1 = program name, 2 = version number, 3 = subversion
tkis_handle_patches(){
  if [[ $1 == "" ]] ; then
    error "tkis_handle_patches(): program name not supplied while trying to process $color_reset$color_notice$rule_name$color_reset$color_error on line #$color_reset$color_notice$current$color_reset$color_error for $color_reset$color_notice$tkis_process"
  fi

  if [[ $2 == "" ]] ; then
    error "tkis_handle_patches(): version number for $color_reset$color_notice$1$color_error not supplied while trying to process $color_reset$color_notice$rule_name$color_reset$color_error on line #$color_reset$color_notice$current$color_reset$color_error with $color_reset$color_notice$1$color_reset$color_error for $color_reset$color_notice$tkis_process"
  fi

  local found=
  local PATCHES=
  local patched_file=

  debug "executing: tkis_get_patches $1 $2 $3"
  tkis_get_patches $1 $2 $3
 
  mkdir -p $tkis_data

  debug "found the following patches: $PATCHES"
  for i in $PATCHES ; do

    debug "Now processing patch $i"

    if [ -f ${tkis_data}patched-$1.$tkis_process ] ; then
      if [[ $(grep -s "^$i$" ${tkis_data}patched-$1.$tkis_process) == "" ]] ; then

        if ! [ -d ${PA}$1 ] ; then
          error "tkis_handle_patches(): $color_reset$color_notice$PA$1$color_error does not exist, cannot be accessed, or is not a directory"
        fi

        if [[ -f ${PA}$1/$1-$2-$i.patch ]] ; then
          patched_file="$1-$2-$i.patch"
          patch -p1 -i ${PA}$1/$1-$2-$i.patch
        elif [[ $3 != "" && -f ${PA}$1/$1-$3-$i.patch ]] ; then
          patched_file="$1-$3-$i.patch"
          patch -p1 -i ${PA}$1/$1-$3-$i.patch
        else
          if [[ $3 == "" ]] ; then
            error "tkis_handle_patches(): Could not find $color_reset$color_notice$1-$2-$i.patch "
          else
            error "tkis_handle_patches(): Could not find either $color_reset$color_notice$1-$2-$i.patch$color_error or $color_reset$color_notice$1-$3-$i.patch "
          fi
        fi

        if ! [ $? -eq 0 ] ; then
          error "tkis_handle_patches(): Failed to apply the patch $color_reset$color_notice$patched_file"
        fi

        echo $i >> ${tkis_data}patched-$1.$tkis_process
        notice "Successfully applied the patch $color_reset$color_notice$patched_file"
      else
        warning "The patch $color_reset$color_notice$i$color_reset$color_warning is already applied, skipping"
      fi

    else
      if [[ -f ${PA}$1/$1-$2-$i.patch ]] ; then
        patched_file="$1-$2-$i.patch"
        patch -p1 -i ${PA}$1/$1-$2-$i.patch
      elif [[ $3 != "" && -f ${PA}$1/$1-$3-$i.patch ]] ; then
        patched_file="$1-$3-$i.patch"
        patch -p1 -i ${PA}$1/$1-$3-$i.patch
      else
        if [[ $3 == "" ]] ; then
          error "tkis_handle_patches(): Could not find $color_reset$color_notice$1-$2-$i.patch "
        else
          error "tkis_handle_patches(): Could not find either $color_reset$color_notice$1-$2-$i.patch$color_error or $color_reset$color_notice$1-$3-$i.patch "
        fi
      fi

      if ! [ $? -eq 0 ] ; then
        error "tkis_handle_patches(): Failed to apply the patch $color_reset$color_notice$patched_file"
      fi

      echo $i >> ${tkis_data}patched-$1.$tkis_process
      notice "Successfully applied the patch $color_reset$color_notice$patched_file"
    fi
  done
}

# 1 = program name, 2 = version number
tkis_handle_cleanup(){
  if [[ $1 == "" ]] ; then
    error "tkis_handle_cleanup(): program name not supplied while trying to process $color_reset$color_notice$rule_name$color_reset$color_error on line #$color_reset$color_notice$current$color_reset$color_error with $color_reset$color_notice$tkis_process"
  fi

  if [[ $2 == "" ]] ; then
    error "tkis_handle_cleanup(): version number for $color_reset$color_notice$1$color_error not supplied while trying to process $color_reset$color_notice$rule_name$color_reset$color_error on line #$color_reset$color_notice$current$color_reset$color_error with $color_reset$color_notice$tkis_process$color_reset$color_error for $color_reset$color_notice$1"
  fi

  if [ -d $WO$1-$2 ] ; then
    debug "executing: rm -Rf ${WO}$1-$2"
    rm -Rf ${WO}$1-$2

    if ! [ $? -eq 0 ] ; then
      error "tkis_handle_cleanup(): rm -Rf $color_reset$color_notice${WO}$1-$2$color_error failed for some reason"
    fi
  else
    debug "$WO$1-$2 does not exist and therefore the cleanup of that directory is being skipped"
  fi
  
  if [ -f ${tkis_data}patched-$1.$tkis_process ] ; then
    debug "executing: rm -Rf ${tkis_data}patched-$1.$tkis_process"
    rm -Rf ${tkis_data}patched-$1.$tkis_process

    if ! [ $? -eq 0 ] ; then
      error "tkis_handle_cleanup(): rm -Rf $color_reset$color_notice${tkis_data}patched-$1.$tkis_process$color_error failed for some reason"
    fi
  else
    debug "${tkis_data}patched-$1.$tkis_process does not exist and therefore the cleanup of that directory is being skipped"
  fi

  if [[ $install_deprecated_documentation == "no" ]] ; then rm -Rf /documentation/{man{,?},info,gtk-doc,doc,docs}; fi

  if [[ $tkis_resume_rule != "" && -f $tkis_resume_rule.$program_name ]] ; then
    rm -f $tkis_resume_rule.$program_name
  fi
}

# there is a nasty bug if I just pushd &>/dev/null
# in the case where /dev/null does not exist
# if /dev/null gets created by this, then all things using /dev/null will have trouble!
# therefore, only echo into null if the null device exists!
push_to_null(){
  notice "Pushing the directory $color_reset$color_notice$1$color_reset$color_highlight onto the directory stack"

  if [ -e /dev/null ] ; then
    pushd $1 &>/dev/null
  else
    pushd $1
  fi

  if ! [ $? -eq 0 ] ; then
    error "push_to_null(): Failed to change into the directory $color_reset$color_notice$1"
  fi
}

# there is a nasty bug if I just popd &>/dev/null
# in the case where /dev/null does not exist
# if /dev/null gets created by this, then all things using /dev/null will have trouble!
# therefore, only echo into null if the null device exists!
pop_to_null(){
  notice "Popping the directory stack"

  if [ -e /dev/null ] ; then
    popd &>/dev/null
  else
    popd
  fi

  if ! [ $? -eq 0 ] ; then
    error "pop_to_null(): Failed to pop the directory stack"
  fi
}

tkis_load_list(){
  local list_files=$(ls ${SY})
  local i=
  local found_name=
  local found_list=
  local list_file=

  # The newer, faster, and much less tested search method
  for i in $list_files ; do
    debug "Searching for List: $tkis_process inside of ${SY}$i"

    found_list=$(fss_basic_list_read -c 0 -s -n $tkis_process ${SY}$i)

    if [[ $found_list != "" ]] ; then
      if [[ $LIST_FILE == "" ]] ; then
        debug "Found List: $tkis_process inside of ${SY}$i"
        list_file=$i
        LIST_FILE=$i
      else
        warning "Found another list by the of $color_reset$color_notice$tkis_process$color_reset$color_warning in the file $color_reset$color_notice${SY}$i$color_reset$color_warning, but are already using the file $color_reset$color_notice${SY}$found_list"
      fi
    fi
  done

  # now that the search is done, confirm status
  if [[ $LIST_FILE == "" ]] ; then
    error "tkis_load_list(): No list by the name of $color_reset$color_notice$tkis_process$color_error was found in any of the systems files: $color_reset$color_notice$(echo $list_files | sed -e 's|\n| |g')"
  fi

  debug "Loading List: $tkis_process from ${SY}$LIST_FILE"
  LIST_DATA=$(fss_basic_list_read -c 0 -n $tkis_process ${SY}$LIST_FILE)

  if [[ $LIST_DATA == "" ]] ; then
    error "tkis_load_list(): The build/list $color_reset$color_notice$tkis_process$color_error was not found inside $color_reset$color_notice$SY$LIST_FILE"
  fi
}

# a simple directory change for rules to use so that a resume will work properly
tkis_local_push(){
  local subdir=$(echo $2 | sed -e 's|^[[:space:]]*||');

  if [[ $1 == "" ]] ; then
    error "tkis_local_push(): The first parameter '$color_reset${color_notice}$1${color_reset}${color_error}' should be either 'absolute', 'program', or 'work', for the rule '$color_reset${color_notice}$rule_name$color_reset${color_error}' in the file '$color_reset$color_notice${RU}$list_filename/$program_name$color_reset${color_error}' on the line $color_reset$color_notice$current_line"
  fi

  if [[ $subdir == "" && $1 != "program" && $1 != "work" ]] ; then
    error "tkis_local_push(): The second parameter was not provided, for the rule '$color_reset${color_notice}$rule_name$color_reset${color_error}' in the file '$color_reset$color_notice${RU}$list_filename/$program_name$color_reset${color_error}' on the line $color_reset$color_notice$current_line"
  fi

  if [[ $1 == "absolute" ]] ; then
    if [ ! -d $subdir ] ; then
      error "tkis_local_push(): The directory '$color_reset${color_notice}$subdir$color_reset${color_error}' does not exist or cannot be accessed, unable to change directory as requested by the rule '$color_reset${color_notice}$rule_name$color_reset${color_error}' in the file '$color_reset$color_notice${RU}$list_filename/$program_name$color_reset${color_error}' on the line $color_reset$color_notice$current_line"
    fi

    notice "Local directory push into $color_reset$color_notice$subdir"
    echo $subdir > ${tkis_data}$tkis_process.last_directory.$program_name
    cd $subdir
  elif [[ $1 == "program" ]] ; then
    if [[ $program_name == "" ]] ; then
      error "tkis_local_push(): The name of the program is not defined, you cannot use 'program' as a parameter for tkis_local_push for an instruction, only use this with a package"
    fi
    if [[ $version == "" ]] ; then
      error "tkis_local_push(): The name of the version is not defined, you cannot use 'program' as a parameter for tkis_local_push for an instruction, only use this with a package"
    fi
    if [ ! -d $WO$program_name-$version/$subdir ] ; then
      error "tkis_local_push(): The directory '$color_reset${color_notice}$WO$program_name-$version/$subdir$color_reset${color_error}' does not exist or cannot be accessed, unable to change directory as requested by the rule '$color_reset${color_notice}$rule_name$color_reset${color_error}' in the file '$color_reset$color_notice${RU}$list_filename/$program_name$color_reset${color_error}' on the line $color_reset$color_notice$current_line"
    fi

    notice "Local directory push into $color_reset$color_notice$WO$program_name-$version/$subdir"
    echo $WO$program_name-$version/$subdir > ${tkis_data}$tkis_process.last_directory.$program_name
    cd $WO$program_name-$version/$subdir
  elif [[ $1 == "work" ]] ; then
    if [ ! -d $WO$subdir ] ; then
      error "tkis_local_push(): The directory '$color_reset${color_notice}$subdir$color_reset${color_error}' does not exist or cannot be accessed, unable to change directory as requested by the rule '$color_reset${color_notice}$rule_name$color_reset${color_error}' in the file '$color_reset$color_notice${RU}$list_filename/$program_name$color_reset${color_error}' on the line $color_reset$color_notice$current_line"
    fi

    notice "Local directory push into $color_reset$color_notice$WO/$subdir"
    echo $WO$subdir > ${tkis_data}$tkis_process.last_directory.$program_name
    cd $WO$subdir
  fi
}

# a simple directory leave for rules to use so that a resume will work properly
tkis_local_pop(){
  rm -f ${tkis_data}$tkis_process.last_directory.$program_name
}
