#!/usr/bin/env bash
#clear
#export PS4='\e[90m+${LINENO} in ${#BASH_SOURCE[@]}>${FUNCNAME[0]}:${BASH_SOURCE[@]##*/} \e[0m'
#set -x

#echo "starting: $0 <LOG_LEVEL=$1>"

symbolicLink.create()     # <sourcePath> for <?user1> <?user2>... # A symbolic link is created to the given users´ home directory or all users´ home directory of the given path+directory # an example
{
  symLinkMode="create"
  sourcePath="$1"
  if [ -n "$sourcePath" ]; then
    shift
    info.log "sourcePath is set to $sourcePath"
  else
    create.result 1 "Source path missing. Using: $sourcePath"
    exit "$(result)"
  fi

  if check dir "$sourcePath" not exists
  then
    create.result 1 "$sourcePath does not exist"
    echo "$sourcePath does not exist"
    exit "$(result)"
  fi
  
  debug.log "create"
  RETURN=$1
}

symbolicLink.delete()     # <linkPath> for <?user1> <?user2>... # A symbolic link is created to the given users' home directory or all users' home directory of the given path+directory # an example
{
  symLinkMode="delete"
  linkPath="$1"
  if [ -n "$linkPath" ]; then
    shift
    info.log "linkPath is set to $linkPath"
  else
    create.result 1 "Link path missing. Using: $linkPath"
    echo "$linkPath does not exist"
    exit "$(result)"
  fi
  
  debug.log "delete"
  RETURN=$1
}

symbolicLink.users() # #
{
  local thePath
  if [ $symLinkMode = "create" ]; then
    thePath=$sourcePath
  fi
  if [ $symLinkMode = "delete" ]; then
    thePath=$linkPath
  fi

  if [ -n "$all" ]; then
    allUsers=$(getent passwd | awk -F: '$3>999 && $3 <5000{print $1}')

    if [ $symLinkMode = "create" ]; then
      symbolicLink create $thePath at $targetDir called $called group $group users $allUsers
    fi
    if [ $symLinkMode = "delete" ]; then
      symbolicLink delete "$thePath" group "$group" users "$allUsers"
    fi

  else
    local user="$1"
    if [ -z "$user" ]; then 
      user="$(whoami)"
    fi

    symbolicLink.exec
    
  fi

  #RETURN=$1
  return $(result)
}

symbolicLink.exec() { 

  source fs

  while [ -n "$user"  ];
    do
      if check user $user exists fix error.log "$user is not a user"
      then
        info.log "user is set to $user"

        IFS='/'
        read -ra parts <<< "$thePath"
        local iAmount=${#parts[*]}
        local lastDir=${parts[iAmount-1]}

        if [ $symLinkMode = "delete" ]; then
          if [[ $iAmount > 1 ]]; then
            thePath="$thePath"
          elif [[ $iAmount == 1 ]]; then
            if fs.user_home $user
            then
              thePath="$RESULT/$thePath"
            else
              info.log "No user home for user $user"
              break
            fi
            #thePath="/home/$user/$thePath"
          fi

          if check dir "$thePath" exists
          then            
            if [[ -L ${thePath} ]]; then
              sudo rm -R "$thePath"
              if [[ -n $group ]];then
                sudo deluser "$user" "$group"
              elif [[ -n $its ]]; then
                sudo deluser "$user" "$lastDir"
              fi
            else
              create.result 1 "The link $thePath for usre $user is not a symbolic link"
              echo "The link $thePath for usre $user is not a symbolic link"
            fi
          else
            create.result 1 "The symbolic link $thePath does not exist for user $user"
            echo "The symbolic link $thePath does not exist for user $user"          
          fi
        fi

        if [ $symLinkMode = "create" ]; then

          if [[ -z $called ]]; then
            if [[ -z $targetDir ]]; then
              targetDir="$lastDir"
            fi
            called=$lastDir
          elif [[ -z $targetDir ]]; then
            targetDir="$called"
          fi

          #   targetDir="${thePath%\/*}/$called"

          # if [[ ! ${thePath::1} == "/" ]]; then
          #   targetDir="/$targetDir"
          # fi

          local target

          if fs.user_home $user
          then
            target=$RESULT
          else
            info.log "No user home for user $user"
            break
          fi

          if [[ $targetDir != $called && $called != $lastDir ]]; then
            sudo mkdir -p "$target/$targetDir"
            sudo setfacl -R -m u:$user:rwx "$target/$targetDir"
            target="$target/$targetDir"
          fi

          if [[ $called == $lastDir ]]; then
            local alreadyDir="$target/$lastDir"
          else
            local alreadyDir="$target/$called"
          fi

          if check dir "$alreadyDir" exists
          then
            local answer
            echo "The destination already exist, do you want to replace $alreadyDir (Y/N)?"
            read answer
            info.log "$answer"
            if [[ $answer =~ ^[Yy]$ ]];
            then
              symbolicLink delete "$alreadyDir" users "$user"
              info.log "$alreadyDir has been deleted"
              local replaced=true
            else
              echo "$alreadyDir is not replaced"
              info.log "$alreadyDir is not deleted"
              break
            fi
          fi

          sudo ln -s "$thePath" --target-directory="$target"
          if [[ $called != $lastDir ]]; then
            sudo mv -f "$target/$lastDir" "$target/$called"
          fi

          if [ -n "$replaced" ]; then
            echo "$alreadyDir has been replaced"
            info.log "$alreadyDir has been replaced"
          fi

          if [[ -n $group ]];then
            sudo groupadd $group
            sudo usermod -a -G $group $USER
            sudo chgrp -R $group "$target/$called"
          else
            sudo groupadd $called
            sudo usermod -a -G $called $USER
            sudo chgrp -R $called "$target/$called"
          fi
          #sudo chown -r $user "$target$called"
          sudo setfacl -R -m u:$user:rwx "$target/$called"
          create.result 0 "thePath is linked to $user"
        fi
      fi
      shift
      user="$1"
    done
    RETURN=$1
    return $(result)
}

noParameter=("called" "in" "for" "users" "group" "at") # if one of these words is $1 when a parameter is expected then it cause the paramter to be skipped

symbolicLink.for() { # <mode:users> # createLink for either specific user(s) or all users
  debug.log "for"
  RETURN=$1
}

symbolicLink.for.completion.mode() { # #
  echo "all"
  echo "users"
}

symbolicLink.all() { # <mode:users> # createLink for all users
  all=true
  RETURN=$1
}

symbolicLink.all.completion.mode() { #  #
  echo "users"
}

symbolicLink.at() { # <mode:destination> # set the destination where the symbolic link should go
  
  if [[ ! " ${noParameter[*]} " =~ " ${1} " ]]; then
    targetDir="$1"
    shift
  fi

  RETURN=$1
}

symbolicLink.at.completion.mode() { #  #
  echo "destination folder"
}

symbolicLink.called() { # <mode:name> # state the name of the symbolic link
  
  if [[ ! " ${noParameter[*]} " =~ " ${1} " ]]; then
    called="$1"
    shift
  fi

  RETURN=$1
}

symbolicLink.called.completion.mode() { #  #
  echo "symbolic link name"
}

symbolicLink.in() { #  #
  debug.log "in"
  RETURN=$1
}

symbolicLink.in.completion.mode() { # #
  echo "group"
}

symbolicLink.out() { #  #
  debug.log "out"
  RETURN=$1
}

symbolicLink.out.completion.mode() { # #
  echo "of"
}

symbolicLink.of() { #  #
  debug.log "out"
  RETURN=$1
}

symbolicLink.of.completion.mode() { # #
  echo "group"
  echo "it's"
}

symbolicLink.its() { #  #
  its="it's"
  RETURN=$1
}

symbolicLink.its.completion.mode() { # #
  echo "group"
}

symbolicLink.group() { # <mode:group> # the name of the group the user should be added
 
  if [[ ! " ${noParameter[*]} " =~ " ${1} " ]]; then
    group="$1"
    shift
  fi

  RETURN=$1
}

symbolicLink.group.completion.mode() { #  #
  echo "user group to add symbolic link"
}

### new.method

symbolicLink.usage()
{
  local this=${0##*/}
  echo "You started" 
  echo "$0

  symbolicLink manages symbolic links, with the following properties:
    1. create a symbolic link with the necessary parameters
    2. delete a symbolic link with the necessary parameters

  Usage:
  $this: command   Parameter and Description"
  this.help
  echo "
  
  Examples
    $this v
    $this init
    $this create /var/dev for users snet shiftAdmin
    $this create /var/dev at ~/ for users snet shiftAdmin
    $this create /var/dev called oosh in group dev for all users
    $this create /var/dev at ~/tmp called oosh in group dev for all users
    $this create /var/dev called oosh in group oosh for all users
    $this create /var/dev at ~/tmp called oosh out of its group for all users
    $this create /var/dev for all users
    $this delete /var/dev for users snet shiftAdmin
    $this delete /var/dev for all users
    $this delete /var/dev out of group dev for users snet
    $this delete /var/dev out of its group for all users
    ----------
  "
}

symbolicLink.start()
{
  #echo "sourcing init"
  source this
  source fs

  # if [ -z "$1" ]; then
  #   status.discover "$@"
  #   return 0
  # fi

  this.start "$@"
}

symbolicLink.start "$@"

