#!/bin/bash
#set -x
#  Copyright (c) 2010 Fizians SAS. <http://www.fizians.com>
#  This file is part of Rozofs.
#  Rozofs is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published
#  by the Free Software Foundation, version 2.
#  Rozofs is distributed in the hope that it will be useful, but
#  WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#  General Public License for more details.

#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see
#  <http://www.gnu.org/licenses/>.

TMP="/tmp/$$.rozo_trash"

#______________________________________
syntax () {

  case "$1" in
    "");;
    *) echo  $1;;
  esac   
  echo " "
  printf "                         -- \033[1m ROZOFS TRASH Utility  \033[0m --\n\n"
  echo " "
  printf " \033[1mrozo_trash <enable|disable> [recursive] [pathname]\033[0m  \tEnable/disable trash on directory pathname (default pathname is \".\").\n"
  echo " "
  printf " \033[1mrozo_trash root <enable|disable> [pathname]\033[0m  \t\tEnable/disable root trash on directory pathname (default pathname is \".\").\n"
  echo " "
  printf "\033[1m rozo_trash status [pathname]\033[0m            \t\tQuery trash status for a directory pathname (default pathname is \".\").\n"
  echo " "
  printf " \033[1mrozo_trash help  \033[0m                        \t\tThis help.\n"
  echo " "

  exit 1

}
#______________________________________
fatal () {

  printf "\n"
  printf "\033[1m$1" 
  printf "  !!!\033[0m \n\n"
  
  rm ${TMP} 2>/dev/null

  exit 1
}
#______________________________________


trash_ls () {
  cd @rozofs-trash@/
  case "$1" in
   "") ls -ls ;; 
   *)  {
         if [ -d $1 ] 
	 then 
	 cd $1/@rozofs-del@/
	 ls -ls 
	 else
	 ls -ls *$1
	 fi
	 
       };;
  esac
  cd .. 2>/dev/null
}
#______________________________________
#
# Find out the current active RozoFS exportd 
# from the given path
#
get_active_exportd() {

  pathname=$1
  res=`attr -qg rozofs.export ${pathname} 2>/dev/null`
  if [ $? -ne 0 ]
  then
    fatal "${pathname} is not a RozoFS directory"
  fi

  #
  # This is a RozoFS mountpoint
  #
  instance=`echo ${res} | awk '{print $4}'`
  rozodiag -T mount:${instance} -c mount > ${TMP}
  exports=`awk '{if ($1=="host") print $3}' ${TMP}`
  mnt=`awk '{if ($1=="mount") print $3}' ${TMP}`
  eid=`awk '{if ($1=="eid") print $3}' ${TMP}`

  #
  # Get local hostname when --local option is set
  # (mainly for debug or test environment)
  if [ "${local}" == "YES" ]
  then
    active="$HOSTNAME"
    return
  fi  
    
  # 
  # Find out which of these exports is the active one asking crm
  #
  for export in `echo ${exports} | tr \/ ' '`
  do
    active=`ssh ${export} "crm_resource --resource p-fs-exportd --locate -Q"`
    if [ $? -ne 0 ];
    then
      active=""
      continue
    fi 
    break
  done
}  
#______________________________________
#
# Recursively enable the trash on a directory that
# has subdirectories
#
do_recursive () {
  value=$1
  fid=$2
  dir=$3
  
  #
  # Get active export address as well as eid values
  #
  get_active_exportd ${dir}
  
  #
  # Request the list of all subdirectories
  #
  ssh root@${active} "rozo_du -e ${eid} -i ${fid} -d" > ${TMP}
  if [ $? -ne 0 ]
  then
    fatal "Can not run rozo_du on active export"
  fi
  
  for path in `cat ${TMP} | awk '{print $1}'`
  do
    if [ ${path} != "--" ]
    then
      # 
      # Set recursive mode
      #
      attr -qs rozofs -V "trash=${value}" ${mnt}/${path}
      if [ $? -ne 0 ]
      then
        echo "Can not enable/disable trash on ${mnt}/${path}"
      fi 
    fi     
  done 
  
  
   
}  
#______________________________________
#
# rozo_trash <enable| disable|recursive| status> [pathname]
#  set/reset trash mode on the current directory or the directory given in $2
#
trash_status () {

  command=${1}
  shift 1

  # 
  # Root privileges are required
  #
  if [ ${UID} -ne 0 ]
  then
    fatal "You need to have root privileges for this operation"
  fi
      
  #
  # Optionnaly recursive mode is requested
  #    
  if [ "$1" == "recursive" ]
  then 
    recursive="YES"
    shift 1
  else
    recursive="NO"
  fi       
            
  # 
  # Path is optionnal 
  #    
  case "$1" in
    "") dir=${PWD};;
    *)  dir=$1;;
  esac
  
  #
  # Check that the directory exist
  #
  if [ ! -d ${dir} ]  
  then
    fatal "${dir} is not a directory"
  fi      
  
  # 
  # Check the directory is under RozoFS 
  #
  attr -qg rozofs ${dir} > ${TMP}
  if [ $? -ne 0 ]
  then
    fatal "${dir} is not a RozoFS directory"
  fi
  
  #
  # Set the requested value
  #
  case "${command}" in
    "disable") value="0";;
    "enable") {     
      if [ "${recursive}" == "YES" ]
      then
        value="2"
      else
        value="1"
      fi
    };;
    *) fatal "Unexpected value ${1}";;
  esac
  attr -qs rozofs -V "trash=${value}" ${dir} > /dev/null
  if [ $? -ne 0 ]
  then
    fatal "rozo_trash $1 ${dir} failed"
  fi
  
  #
  # In recursive mode, 
  # trash must be enabled/disabled on all pre-existing sub-directory 
  #
  if [ "${recursive}" == "YES" ]
  then
    nlink=`awk '{if ($1=="NLINK") {print $3}}' ${TMP}`
    if [ ${nlink} -ne 2 ]
    then  
      #
      # Need to propagate to every subdirectory
      #
      fid=`awk '{if ($1=="FID") {print $3}}' ${TMP}`
      do_recursive ${value} ${fid} ${dir}
    fi 
  fi

  trash_status_display $dir
}

#______________________________________
#
# rozo_trash <enable| disable|recursive| status> [pathname]
#  set/reset trash mode on the current directory or the directory given in $2
#
trash_status_display () {
  case "$1" in
    "") dir=".";;
    *) dir=$1;;
  esac 
     
  res=`attr -g rozofs $dir | awk -F':' '{if ($1=="TRASH   ") print $2;}'`
  case "$res" in 
    " YES") echo "Trash is enabled on $dir";;
    " YES (RECURSIVE)") echo "Trash is enabled in recursive mode on $dir";;
    *)    echo "Trash is disabled on $dir";;
 esac
  res=`attr -g rozofs $dir | awk '{if ($1=="R_TRASH") print $3;}'`
  case "$res" in 
    "YES") echo "Root Trash is enabled on $dir";;
    *)    echo "Root Trash is disabled on $dir";;
 esac
}

#______________________________________
#
# rozo_trash root <enable| disable | status> [pathname]
#  set/reset trash mode on the current directory or the directory given in $2
#
trash_root () {
  case "$2" in
    "") dir=".";;
    *) dir=$2;;
  esac 
  case "$1" in
    "enable") attr -s rozofs -V "root-trash=1" $dir > /dev/null;;
    "disable") attr -s rozofs -V "root-trash=0" $dir > /dev/null;;
  esac   
  trash_status_display $dir
}
#______________________________________
#
# rozo_trash purge 
#

trash_purge_internal () {
  dir=$1
  res=$2
  res1=$2
  local f=""
  cd $dir/@rozofs-trash@/

  for f in  ` ls -d $res `
  do
    echo "$f "
    if [ -d $f ]
    then
     trash_purge_internal $f "$2"
     rmdir $f
    else
     rm -f $f  
    fi 
  done
  cd ../..


}
trash_purge () {

  printf "enter a filename or wildcard: "
  read res
  trash_purge_internal "." $res
  echo "Done."
}
#______________________________________
#
# rozo_trash rm <path> 
#
trash_rm () {
  cd @rozofs-trash@/
  case "$1" in 
    "") syntax "Restore requires a parameter";;
  esac 
  for f in  ` ls *$1*`
  do
    echo "remove $f (y/n) ?"
    read res
    case "$res" in
    y|Y|yes|YES) rm -rf $f;;
    esac
   
  done
   cd ..
}
#______________________________________
#
#  restore the content of a deleted directory
trash_restore_directory(){
  src=$1
  dst=$2
  
  dir_date=`echo $src | awk -F'@' '{ print $2}'`
  cd $dst  
  for f in `ls @rozofs-trash@/@$dir_date@@* ` 
  do
    dfname=`echo $f | awk -F'@' '{ print $6}'`
    sfname=`echo $f | awk -F'/' '{ print $2}'`
    trash_restore $sfname $dfname
  done
}
#______________________________________
#
# rozo_trash restore <source> <destination> 
#
trash_restore() {

  src=$1
  shift 1
  case "$src" in 
    "") syntax "Restore requires a source file name";;
  esac  

  if [ ! -e @rozofs-trash@/$src ];
  then
     syntax "Source file name \"$src\" does not exist"
  fi
  dst=$1
  shift 1
  case "$dst" in 
    "") syntax "Restore requires a destination file name";;
  esac  

  if [ -e $dst ];
  then
     syntax "Destination file name \"$dst\" already exists"
  fi  
# restore the requested object  
  mv @rozofs-trash@/$src $dst
# check if a full directory has to be restored
  if [  -d $dst ];
  then
     trash_restore_directory  $src $dst
  fi
}
#______________________________________
set_command() {
  if [ "${command}" == "" ]
  then
    command=$1
  else
    syntax "${command} and $1 afre incompatible"
  fi
} 
#______________________________________
local="NO"
recursive="NO"
command=""

while [ ! -z $1 ];
do   
  case "$1" in 
    "-v")           set -x; shift 1;;
    "--local")      local="YES"; shift 1;;
    *) break;;
  esac
done

cmd=$1
shift 1
case "${cmd}" in
  enable)    trash_status enable $* ;;  
  recursive) trash_status enable recursive $* ;;  
  disable)   trash_status disable $*;;  
  status)    trash_status_display  $1 2>/dev/null ;;  
  root)      trash_root  $1 $2 2>/dev/null;;  

#  dir) trash_restore_directory  $1 $2 2>/dev/null;;  
  *) syntax;;
esac

rm ${TMP} 2>/dev/null
