#!/usr/bin/wish

# This file provides many valuable data processing procedures like
# lappend_unique, get_var, etc.


proc lappend_unique { args } {

  # Add the each entry to a list if and only if they do not already exist in
  # the list.

  # Description of argument(s):
  # args                            The first argument should be the list
  #                                 name.  All other arguments are items to be
  #                                 added to the list.

  set list_name [lindex $args 0]
  # Remove first entry from args list.
  set args [lreplace $args 0 0]

  upvar 1 $list_name list

  if { ! [info exists list] } { set list {} }

  foreach arg $args {
    if { [lsearch -exact $list "${arg}"] != -1 } { continue }
    lappend list $arg
  }

}


proc lsubtract {main_list_name removal_list} {
  upvar $main_list_name ref_main_list

  # Remove any entry from the main list that is contained in removal list.

  # Description of argument(s):
  # main_list_name                  The name of your master list.
  # removal_list                    The list of items to be removed from
  #                                 master list.

  # For each element in the removal list, find the corresponding entry in the
  # master list and remove it.
  for {set removal_ix 0} {$removal_ix < [llength $removal_list ]}\
      {incr removal_ix} {
    set value [lindex $removal_list $removal_ix]
    set master_ix [lsearch $ref_main_list $value]
    set ref_main_list [lreplace $ref_main_list $master_ix $master_ix]
  }

}


proc list_map { list expression } {

  # Create and return a new list where each element of the new list is a
  # result of running the given expression on the corresponding entry from the
  # original list.

  # Description of argument(s):
  # list                            A list to be operated on.
  # expression                      A command expression to be run on each
  #                                 element in the list (e.g. '[string range
  #                                 $x 1 end]').

  foreach x $list {
    set cmd_buf "lappend new_list ${expression}"
    eval $cmd_buf
  }

  return $new_list

}


proc list_filter { list expression } {

  # Create and return a new list consisting of all elements of the original
  # list that do NOT pass the expression.

  # Description of argument(s):
  # list                            A list to be operated on.
  # expression                      A command expression to be run on each
  #                                 element in the list (e.g. 'regexp
  #                                 -expanded {^[[:blank:]]*\#|^[[:blank:]]*$}
  #                                 $x', 'string equal $x ""', etc.).

  set new_list {}

  foreach x $list {
    set cmd_buf "set result \[${expression}\]"
    eval $cmd_buf
    if { ! $result } { lappend new_list $x }
  }

  return $new_list

}


proc list_filter_comments { list } {

  # Filter comments from list and return new_list as a result.

  # Description of argument(s):
  # list                            A list to be operated on.

  set comment_regexp {^[[:blank:]]*\#|^[[:blank:]]*$}

  set new_list [list_filter $list "regexp -expanded {$comment_regexp} \$x"]

  return $new_list

}


proc get_var { var_var { default ""} } {
  upvar 1 $var_var var_ref

  # Return the value of the variable expression or the value of default if
  # the variable is not defined.

  # Example use:
  # set PATH [get_var ::env(PATH) "/usr/bin"]

  # Description of argument(s):
  # var_var                         The name of a variable (e.g.
  #                                 "::env(NANOSECOND)" or "var1").
  # default                         The default value to return if the
  #                                 variable named in var_var does not exist.

  expr { [info exists var_ref] ? [return $var_ref] : [return $default] }

}


proc set_var_default { var_name { default ""} } {
  upvar 1 $var_name var_ref

  # If the variable named in var_name is either blank or non-existent, set
  # its value to the default.

  # Example use:
  # set_var_default indent 0

  # Description of argument(s):
  # var_name                        The name of a variable.
  # default                         The default value to assign to the
  #                                 variable if the variable named in var_name
  #                                 is blank or non-existent.

  if { ! ([info exists var_ref] && $var_ref != "") } {
    set var_ref $default
  }

}


proc split_path {path dir_path base_name} {
  upvar $dir_path ref_dir_path
  upvar $base_name ref_base_name

  # Split a path into it's dir_path and base_name.  The dir_path variable
  # will include a trailing slash.

  # Description of argument(s):
  # path                            The directory or file path.
  # dir_path                        The variable to contain the resulting
  #                                 directory path which will include a
  #                                 trailing slash.
  # base_name                       The variable to contain the resulting base
  #                                 directory or file name.

  set ref_dir_path "[file dirname ${path}]/"
  set ref_base_name "[file tail $path]"

}


proc read_properties_file {parm_file_path} {

  # Read properties files and return key/value pairs as a list.

  # Description of argument(s):
  # parm_file_path                  The path to the properties file.

  # The properties file must have the following format:
  # var_name=var_value
  # Comment lines (those beginning with a "#") and blank lines are allowed
  # and will be ignored.  Leading and trailing single or double quotes will be
  # stripped from the value.  E.g.
  # var1="This one"
  # Quotes are stripped so the resulting value for var1 is:
  # This one

  # Suggestion: The caller can then process the result as an array or a
  # dictionary.

  # Example usage:

  # array set properties [read_properties_file $file_path]
  # print_var properties

  # With the following result...

  # properties:
  #   properties(command):  string

  # Or...

  # set properties [read_properties_file $file_path]
  # print_dict properties

  # With the following result...

  # properties:
  #   properties[command]:  string

  # Initialize properties array.

  set properties [list]

  # Read the entire file into a list, filtering comments out.
  set file_descriptor [open $parm_file_path r]
  set file_data [list_filter_comments [split [read $file_descriptor] "\n"]]
  close $file_descriptor

  foreach line $file_data {
    # Split <var_name>=<var_value> into component parts.
    set pair [split $line =]
    lappend properties [lindex ${pair} 0]
    lappend properties [string trim [lindex ${pair} 1] {"}]
  }

  return $properties

}


proc convert_array_key {key {convert_commands} {prefix ""} } {

  # Convert the key according to the caller's convert_commands and return the
  # result.

  # This is designed as a helper procedure to be called by convert_array_keys.

  # See convert_array_keys for description of arguments.

  set new_key $key
  foreach command $convert_commands {
    if { $command == "prefix" } {
      regsub -all "^$prefix" $new_key {} new_key
      set new_key "$prefix$new_key"
    } elseif { $command == "rm_prefix" } {
      regsub -all "^$prefix" $new_key {} new_key
      set new_key "$new_key"
    }
    if { $command == "upper" } {
      set new_key [string toupper $new_key]
    } elseif { $command == "lower" } {
      set new_key [string tolower $new_key]
    }
  }

  return $new_key

}


proc convert_array_keys {source_arr target_arr {convert_commands}\
  {prefix ""} } {
  upvar $source_arr source_arr_ref
  upvar $target_arr target_arr_ref

  # Convert the keys of source_arr according to the caller's convert_commands
  # and put the resulting array in target_arr. If this procedure fails for any
  # reason, it will return non-zero.

  # Note that despite the name of this procedure, it will also work on a
  # dictionary.  In other words, if source_arr is NOT an array, it will be
  # processed as a dictionary and target_arr will be created as a dictionary
  # as well.

  # Description of argument(s):
  # source_arr                      The source array that is to be converted.
  # target_arr                      The target array that results from the
  #                                 conversion.
  # convert_commands                A list of custom commands that indicate
  #                                 the type of conversion(s) the caller
  #                                 wishes to see. Currently the accepted
  #                                 values are as follows:
  #   upper                         Convert key value to uppercase.
  #   lower                         Convert key value to lowercase.
  #   prefix                        Prepend prefix to the key, provided that
  #                                 it does not already exist. If upper or
  #                                 lower is included in convert_commands
  #                                 list, the prefix will be converted to the
  #                                 specified case as well.
  #   rm_prefix                     Remove a prefix that is prepended,
  #                                 provided that it exists.
  # prefix                          The prefix to be used for "prefix" and
  #                                 "rm_prefix" commands (see convert_commands
  #                                 text above).

  # Validate arguments.
  if { [lsearch $convert_commands lower] != -1 } {
    if { [lsearch $convert_commands upper] != -1 } {
      return -code error "Cannot convert to both upper and lower cases."
    }
  }

  if { [lsearch $convert_commands rm_prefix] != -1} {
    if { [lsearch $convert_commands prefix] != -1} {
      return -code error "Cannot add and remove a prefix."
    }
  }

  if { [lsearch $convert_commands prefix] != -1 ||\
       [lsearch $convert_commands rm_prefix] != -1 } {
    if { [lsearch $convert_commands upper] != -1 } {
      set prefix [string toupper $prefix]
    } elseif { [lsearch $convert_commands lower] != -1 } {
      set prefix [string tolower $prefix]
    }
  }

  if { [array exists source_arr_ref] } {
    # Initialize targ array.
    array set target_arr_ref {}
    # Walk the source array doing the conversion specified in convert_commands.
    set search_token [array startsearch source_arr_ref]
    while {[array anymore source_arr_ref $search_token]} {
      set key [array nextelement source_arr_ref $search_token]
      set value $source_arr_ref($key)

      set new_key [convert_array_key $key $convert_commands $prefix]
      set cmd_buf "set target_arr_ref($new_key) $value"
      eval $cmd_buf
    }
    array donesearch source_arr_ref $search_token

  } else {
    # Initialize targ dictionary.
    set target_arr_ref [list]
    # Walk the source dictionary doing the conversion specified in
    # convert_commands.
    foreach {key value} $source_arr_ref {
      set new_key [convert_array_key $key $convert_commands $prefix]
      set cmd_buf "dict append target_arr_ref $new_key \$value"
      eval $cmd_buf
    }
  }

}


proc expand_shell_string {buffer} {
  upvar $buffer ref_buffer

  # Call upon the shell to expand the string in "buffer", i.e. the shell will
  # make substitutions for environment variables and glob expressions.

  # Description of argument(s):
  # buffer                          The buffer to be expanded.

  # This is done to keep echo from interpreting all of the double quotes away.
  regsub -all {\"} $ref_buffer "\\\"" ref_buffer

  # Bash will compress extra space delimiters if you don't quote the string.
  # So, we quote the argument to echo.
  if {[catch {set ref_buffer [exec bash -c "echo \"$ref_buffer\""]} result]} {
    puts stderr $result
    exit 1
  }

}


proc add_trailing_string { buffer { add_string "/" } } {
  upvar $buffer ref_buffer

  # Add the add string to the end of the buffer if and only if it doesn't
  # already end with the add_string.

  # Description of argument(s):
  # buffer                          The buffer to be modified.
  # add_string                      The string to conditionally append to the
  #                                 buffer.

  regsub -all "${add_string}$" $ref_buffer {} ref_buffer
  set ref_buffer "${ref_buffer}${add_string}"

}


