#!/bin/bash

tkis_single_execution(){
  local program_name=$1
  local rule_name=$2

  push_to_null .

  if [ -f ${SE}settings-$list_filename ] ; then
    debug "Loading local settings file: ${SE}settings-$tkis_process"
    tkis_source_file ${SE}settings-$list_filename
  else
    debug "${SE}settings-$list_filename doest not exist or cannot be accessed"
  fi

  debug "Looking for ignore system_versions: \"$(fss_basic_list_read -c 0 -n $tkis_process $SY$list_filename  | grep -s '^ignore system_versions[[:space:]]*$')\""
  if [[ $(fss_basic_list_read -c 0 -n $tkis_process $SY$list_filename  | grep -s "^ignore system_versions[[:space:]]*$") == "ignore system_versions" ]] ; then
    debug "Instructing program to disregard the systems version file"
    tkis_ignore_system_version="yes"
  fi

  debug "Looking for running_on_host: \"$(fss_basic_list_read -c 0 -n $tkis_process $SY$list_filename  | grep -s '^runing_on_host[[:space:]]*$')\""
  if [[ $(fss_basic_list_read -c 0 -n $tkis_process $SY$list_filename  | grep -s "^running_on_host[[:space:]]*$") == "running_on_host" ]] ; then
    debug "Setting security precautions in place to protect the host system from damage"
    tkis_running_on_host="yes"
    tkis_ignore_system_version="yes"
  fi

  if [[ $program_name == "" ]] ; then
    error "tkis_single_execution(): Missing rule file parameter"
  fi

  if [[ $rule_name == "" ]] ; then
    error "tkis_single_execution(): Missing rule's list name parameter for the program $color_reset$color_notice$program_name$color_error inside of $color_reset$color_notice${RU}$tkis_process/$program_name"
  fi

  if [ -f $tkis_local_error.$program_name ] ; then
    error "tkis_single_execution(): The local error file: $color_reset$color_notice$tkis_local_error.$program_name$color_error exists. Fix the problem then delete the local error file to continue"
  fi

  if ! [ -f $RU$tkis_process/$program_name ] ; then
    error "tkis_single_execution(): The rule $color_reset$color_notice$RU$tkis_process/$program_name$color_error is missing or cannot be accessed" 
  fi

  if [ -f $system_version_file ] ; then
    if [[ $(grep -s "^$program_name " $system_version_file) != "" || $(grep -s "^$program_name " ${SE}global_versions) != "" ]] ; then
      warning "$color_reset$color_notice$program_name$color_reset$color_warning looks like a package, use $color_reset$color_notice-u$color_reset$color_warning or $color_reset$color_notice--upgrade$color_reset$color_warning to handle packages, this may fail if the execution is a package"
    fi
  else
    if [[ $(grep -s "^$program_name " ${SE}global_versions) != "" ]] ; then
      warning "$color_reset$color_notice$program_name$color_reset$color_warning looks like a package, use $color_reset$color_notice-u$color_reset$color_warning or $color_reset$color_notice--upgrade$color_reset$color_warning to handle packages, this may fail if the execution is a package"
    fi
  fi

  if [[ -f ${SE}versions-$tkis_process && $(grep -s "^$program_name " ${SE}versions-$tkis_process) != "" ]] ; then
    warning "$color_reset$color_notice$program_name$color_reset$color_warning looks like a package, use $color_reset$color_notice-u$color_reset$color_warning or $color_reset$color_notice--upgrade$color_reset$color_warning to handle packages, this may fail if the execution is a package"
  fi

  # change into our archive now
  if [ -f ${tkis_data}$tkis_process.last_directory.$program_name ] ; then
    if [ ! -d $(cat ${tkis_data}$tkis_process.last_directory.$program_name) ] ; then
      error "tkis_single_execution(): The directory '$color_reset${color_notice}$(cat ${tkis_data}$tkis_process.last_directory.$program_name)$color_reset${color_error}' does not exist or cannot be accessed, unable to change directory as requested by $color_reset$color_notice$rule_name"
    fi

    debug "Going into the directory: $(cat ${tkis_data}$tkis_process.last_directory.$program_name)"
    push_to_null $(cat ${tkis_data}$tkis_process.last_directory.$program_name)
  else
    debug "Going into the directory: ${WO}$program_name-$version"
    push_to_null $WO
  fi

  # prepare to parse list
  local current=0
  local current_line=
  local current_word=
  local list_size=

  # prepare to execute the rules
  debug "Loading List Size: fss_basic_list_read -c 0 -s -n $rule_name ${RU}$tkis_process/$program_name"
  list_size=$(fss_basic_list_read -c 0 -s -n $rule_name ${RU}$tkis_process/$program_name)

  debug "Loading list to check for non-whitespace: fss_basic_list_read -c 0 -n $rule_name ${RU}$tkis_process/$program_name"
  LIST_DATA=$(fss_basic_list_read -c 0 -p -n $rule_name ${RU}$tkis_process/$program_name)

  # now check for non-whitespaces
  if [[ $list_size -le 0 || $LIST_DATA == "" ]] ; then
    warning "There is no data in the list $color_reset$color_notice$rule_name$color_reset$color_warning from the file $color_reset$color_notice${RU}$tkis_process/$program_name"
  fi

  if [[ -f $tkis_resume_rule.$program_name ]] ; then
    current=$(cat $tkis_resume_rule.$program_name)

    # attempt to identify a corrupt/invalid resume file
    local weird=$(echo $(cat $tkis_resume_rule.$program_name) | sed -e 's|0||g' -e 's|1||g' -e 's|2||g' -e 's|3||g' -e 's|4||g' -e 's|5||g' -e 's|6||g' -e 's|7||g' -e 's|8||g' -e 's|9||g')

    # on invalid/corrupt data start from the top
    if [[ $current == "" || $weird != "" ]] ; then
      warning "$color_reset$color_notice$tkis_resume_rule.$program_name$color_reset$color_warning was found but is corrupt or contains invalid data: $color_reset$color_notice$current$color_reset$color_warning; execution will start from the top instead of resuming"
      rm -f $tkis_resume_rule.$program_name
      current=0
    elif [[ $current -lt 0 || $current -ge $list_size ]] ; then
      warning "$color_reset$color_notice$tkis_resume_rule.$program_name$color_reset$color_warning was found but contains invalid resume position: $color_reset$color_notice$current$color_reset$color_warning; execution will start from the top instead of resuming"
      rm -f $tkis_resume_rule.$program_name
      current=0
    fi
  fi

  # make sure LIST_LINE is reset
  LIST_LINE=

  debug "Rule is resuming/starting on line #$current"
  while [ $current -lt $list_size ] ; do
    debug "obtaining list line #$current, \"$rule_name\", \"${RU}$tkis_process/$program_name\""
    LIST_DATA=$(fss_basic_list_read -c 0 -l $current -n $rule_name ${RU}$tkis_process/$program_name)
    current_line=$LIST_DATA

    # for security purposes, remove these variables before executing bash code
    unset LIST_DATA LIST_NAME LIST_SIZE LIST_TOTAL

    if [[ $(echo $current_line | sed -e 's|[[:space:]]||g') != "" ]] ; then
      tkis_execute "$current_line"

      if ! [ $? -eq 0 ] ; then
        error "tkis_single_execution(): $color_reset$color_noticetkis_execute $current_line$color_error failed for some reason"
      fi
    else
      debug "\"tkis_execute $current_line\" was skipped because current_line \"$current_line\" is only whitespace"
    fi

    let current=$current+1

    if [[ $current -lt $list_size ]] ; then
      # save the next spot so resume can work properly
      echo $current > $tkis_resume_rule.$program_name
    fi

  done

  echo "$program_name $rule_name" >> ${tkis_data}installed.$tkis_process

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

  rm -f $tkis_resume_rule.$program_name
  tkis_local_pop

  notice "Successfully executed $color_reset$color_notice$program_name$color_highlight for $color_reset$color_notice$tkis_process"

  # return to our previous location
  debug "popping last directory"
  pop_to_null

  debug "popping to original directory prior to script execution"
  pop_to_null
}
