function __bak_help
  echo -e \
"Usage:
  $argv[1] SOURCE..."
end

function __bak_parse_help
  if [ (count $argv) -lt 3 ]
    __bak_help $argv[1]
  else
    return 1
  end
end

function __bak_name
  # trim / for directories
  set file (echo $argv[1] | sed 's/\/*$//')
  echo "$file."(date +'%Y%m%d_%H%M%S')".bak"
end

function __bak
  __bak_parse_help $argv
  or begin
    set program $argv[2]
    for file in $argv[3..-1]
      eval $program $file (__bak_name $file)
    end
  end
end

set -g __bak_re '(.*)\.[0-9]{8,8}_[0-9]{6,6}\.bak\/*$'

function __is_bak
  set file $argv[1]
  echo "$file" | grep -Eq $__bak_re
end

function __bak_normalized
  set file $argv[1]
  echo "$file" | sed -E "s/$__bak_re/\1/g"
end
  
function __unbak
  __bak_parse_help $argv
  or begin
    set program $argv[2]
    for file in $argv[3..-1]
      set normalized (__bak_normalized $file)
      if test ! -e $file
        echo "File \"$file\" not exists! Cannot unbak \"$file\"."
      else if not __is_bak $file
        echo "File \"$file\" don't meet bak files convention! Cannot unbak \"$file\"."
      else if test -e $normalized
        echo "File \"$normalized\" exists! Cannot unbak \"$file\"."
      else
        eval $program $file $normalized
      end
    end
  end
end