#!/bin/sh

#      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012
#
#  This file is part of RoarAudio PlayList Daemon,
#  a playlist management daemon for RoarAudio.
#  See README for details.
#
#  This file is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License version 3
#  as published by the Free Software Foundation.
#
#  RoarAudio 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 software; see the file COPYING.  If not, write to
#  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
#  Boston, MA 02110-1301, USA.

RPLD_STORE_LOCATION='/var/lib/roarplaylistd/'
RPLD='rpld'
COMMAND='_error'
FORCE=false
HISTSIZE='default'
ROLE='default'

if [ -f /etc/rpld-storemgr.conf ]; then
 . /etc/rpld-storemgr.conf
fi

if [ -f ~/.rpld-storemgr.conf ]; then
 . ~/.rpld-storemgr.conf
fi

# lib:
__test() { test -d "$RPLD_STORE_LOCATION"; }
__mkdir() { mkdir -p "$RPLD_STORE_LOCATION"; }
__rmdir() { rm -rf "$RPLD_STORE_LOCATION"; }
__ask_bool() { read -p "$1 [y/N]: " ret; if [ "$ret" = 'y' -o "$ret" = 'Y' -o "$ret" = 'yes' ]; then true; else false; fi; }
__run() { "$RPLD" --store-path "$RPLD_STORE_LOCATION" --histsize "$HISTSIZE" --role "$ROLE" "$@"; }
# end of lib

# commands:
cmd_help() {
 echo "Usage: $0 [OPTIONS] command [ARGS]"
 cat <<EOF
Options:
 -h --help                 - Show this help.
    --config FILE          - Read an additional config files.
    --store-path PATH      - Sets the store path to PATH.
    --histsize SIZE        - Set size of default history.
    --role ROLE            - Set the stream role for the default queue.
    --force                - Force operation.

Commands:
 help                      - Show this help.
 remove                    - Remove an existing store.
 create [TYPE [SERVER]]    - Create a new store.
 import PLAYLIST TYPE FILE - Import the playlist FILE into PLAYLIST. FILE is of type TYPE.
 export PLAYLIST TYPE FILE - Export the playlist PLAYLIST into FILE. FILE is of type TYPE.
 run [ARGS]                - Start rpld with selected store.
 console [ARGS]            - Start rpld with only the current console connected.
 info                      - Show information about the store.
 check                     - Check store for errors.

Options for command: create
 TYPE
  This is the type of the server to connect to.
  If this is "roar" the server is a normal RoarAudio server.
  If set to "SavannahIce" the server address is understood
  as URL pointing to an Icecast server. A special server
  address is written allowing to stream to the server using
  SavannahIce.
 SERVER
  This is the server address. This is a normal address in case
  of type "roar" or a URL in case of type "SavannahIce".

Options for command: run, console
 Options for commands run and console are directly passed to rpld.
EOF
}

cmd_remove() {
 if __test
 then
  :
 else
  echo "Warning: Can not delete non-existing store."
  return 0;
 fi

 $FORCE || echo "Warning: Removing the store will destroy all your playlists and config safed within the store."
 if $FORCE || __ask_bool "Are you sure you want to delete the store?"
 then
  __rmdir
 fi
}

cmd_create() {
 mode="$1";
 server='+invalid';

 shift;

 [ "$mode" = '' ] && mode='roaraudio';

 case "$mode" in
  'roar'|'roaraudio')
   server="$1";
   shift;
   [ "$server" = '' ] && server='+default';
  ;;
  'SavannahIce'|'savannahice')
   mode='savannahice';
   server="$1";
   shift;
  ;;
  *)
   echo "Error: Unknown mode: $mode" >&2
   return 3;
  ;;
 esac;

 if __test
 then
  echo "Warning: store directory already exists."
  return 0;
 else
  :
 fi

 __mkdir

 if [ "$mode" = 'savannahice' ]
 then
  [ "$server" != '' ] && server=" -O $server";
  {
   echo '#!/bin/sh';
   echo "exec savannahice \"\$@\"$server";
   echo '#ll';
  } > "$RPLD_STORE_LOCATION"/server
  chmod a+rx "$RPLD_STORE_LOCATION"/server
  server="+fork=!$RPLD_STORE_LOCATION/server --no-listen --client-fh 0"
 fi

 __run --no-listen --stopped --no-restore --store --server-queue "$server"
}

cmd_imexport() {
 command="$1"
 playlist="$2"
 type="$3"
 file="$4"

 [ "$type" = '' ] && type='VCLT';
 if [ "$file" = '-' -o "$file" = '' ]
 then
  [ "$command" = 'import' ] && file='/dev/stdin';
  [ "$command" = 'export' ] && file='/dev/stdout';
 fi

 if __test
 then
  :
 else
  echo "Error: Store does not exist."
  return 1;
 fi

 __run --no-listen --stopped --restore --store --playlist-$command "$playlist" "$type" "$file"
}

cmd_run() {
 if __test
 then
  :
 else
  echo "Error: Store does not exist."
  return 1;
 fi

 __run --restore "$@"
}

cmd_info() {
 if __test
 then
  :
 else
  echo "Error: Store does not exist."
  return 1;
 fi

 _version=`cat "$RPLD_STORE_LOCATION"/store-version 2>/dev/null`
 case "$_version" in
  '')
   _version=0
   _version_str='pre 0.1rc1 (assumed)'
  ;;
  '0')
   _version_str='pre 0.1rc1'
  ;;
  '1')
   _version_str='pre 0.1rc7'
  ;;
  '2')
   _version_str='0.1rc7'
  ;;
 esac;

 echo "Store format: $_version: $_version_str"
 echo "Playlists:"
 while IFS=':' read _PLTAG pl_id pl_parent _XTAG pl_name pl_histsize pl_volume pl_role pl_history pl_backend pl_mixer
 do
  if [ "$pl_parent" = '0' ]
  then
   pl_parent='no parent'
  else
   pl_parent="parent: $pl_parent"
  fi

  if [ "$pl_mixer" = '-1' ]
  then
   pl_mixer='default mixer'
  else
   pl_mixer="mixer: $pl_mixer"
  fi

  echo "$pl_id[$pl_parent]: $pl_name"
  [ "$_version" -ge 2 -a "$pl_histsize" != '-1' ] && echo "  Is history with history size $pl_histsize"
  [ "$_version" -ge 2 -a "$pl_backend" != '+invalid' ] && echo "  Is queue with backend $pl_backend[$pl_mixer], volume $pl_volume/65535, role $pl_role and history $pl_history"
 done < "$RPLD_STORE_LOCATION"/index

 echo "Pointers:"
 while IFS=' ' read _POINTERTAG pointer_name _ARROWTAG pointer_value
 do
  pointer_name=`echo "$pointer_name" | cut -d\" -f2`
  echo " $pointer_name set to $pointer_value"
 done < "$RPLD_STORE_LOCATION"/pointer
}

cmd_check() {
 error=false;

 if __test
 then
  :
 else
  echo "Error: Store does not exist."
  return 1;
 fi

 _version=`cat "$RPLD_STORE_LOCATION"/store-version 2>/dev/null`
 [ "$_version" = '' ] && _version=0
 if [ "$_version" = '2' ]
 then
  echo "Store format: 2 - Good."
 elif [ "$_version" -gt '2' ]
 then
  echo "Store format: $_version - greater than current. BAD."
  error=true;
 else
  echo "Store format: $_version - Old. Try to upgrade."
 fi

 while IFS=':' read _PLTAG pl_id pl_parent _XTAG pl_name pl_histsize pl_volume pl_role pl_history pl_backend pl_mixer
 do
  pl_id=`echo "$pl_id" | tr -d ' '`
  if [ -f "$RPLD_STORE_LOCATION/pl-$pl_id" ]
  then
   echo "Playlist $pl_id: exists - Good."
  else
   echo "Playlist $pl_id: does not exist - BAD."
   error=true;
  fi

  if [ "$pl_parent" = '0' ]
  then
   echo "Playlist $pl_id's parent: Playlist has no parent - Good."
  else
   if [ -f "$RPLD_STORE_LOCATION/pl-$pl_parent" ]
   then
    echo "Playlist $pl_id's parant $pl_parent: exists - Good."
   else
    echo "Playlist $pl_id's parent $pl_parent: does not exist - BAD."
    error=true;
   fi
   _res=`grep -c "^PL: $pl_parent:" < "$RPLD_STORE_LOCATION"/index`
   if [ "$_res" = '1' ]
   then
    echo "Playlist $pl_id's parant $pl_parent: is in index - Good."
   elif [ "$_res" = '0' ]
   then
    echo "Playlist $pl_id's parant $pl_parent: is not in index - BAD."
    error=true
   else
    echo "Playlist $pl_id's parant $pl_parent: has bad index count: $_res - BAD."
    error=true
   fi
  fi
 done < "$RPLD_STORE_LOCATION"/index

 $error && return 2;
 return 0;
}
# end of commands


while [ "$1" != '' ]
do
 case "$1" in
  '-h'|'--help')
   cmd_help;
   exit 0;
  ;;
  '--config')
   . "$2"
   shift;
  ;;
  '--store-path')
   RPLD_STORE_LOCATION="$2"
   shift;
  ;;
  '--histsize')
   HISTSIZE="$2"
   shift;
  ;;
  '--role')
   ROLE="$2"
   shift;
  ;;
  '--force')
   FORCE=true
  ;;
  --*)
   echo "Unknown option: $1" >&2
   exit 1;
  ;;
  *)
   COMMAND="$1"
   shift;
   break;
  ;;
 esac;
 shift;
done

case "$COMMAND" in
 help)
  cmd_help;
 ;;
 remove)
  cmd_remove;
 ;;
 create)
  cmd_create "$@";
 ;;
 import|export)
  cmd_imexport "$COMMAND" "$@";
 ;;
 run)
  cmd_run "$@";
 ;;
 console)
  cmd_run --no-listen --client-fh 3 "$@" 3<>`tty`;
 ;;
 info)
  cmd_info;
 ;;
 check)
  cmd_check;
 ;;
 *)
  echo "Unknown command: $COMMAND" >&2
  exit 2;
 ;;
esac

#ll
