# audioscrobbler: ZOMG audioscrobbler functions
#   Copyright (C) 2005, 2006, 2007, 2008, 2009  Clint Adams

# This program 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; either version 3 of the License, or
# (at your option) any later version.

# This program 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, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA

audioscrobbler_handshake() {
  local site="$1"
  local username="$2"
  local password="$3"
  local -a response
  local ret local xferencoding tstamp authtoken

  log_msg "Connecting to $handshake_host[$site] for handshaking.."
  tstamp=$(export TZ=UTC; print ${EPOCHSECONDS})
  local pwsum="$(print -n "${password}" | md5sum | awk '{print $1}')${tstamp}"
  authtoken="$(print -n "${pwsum}" | md5sum | awk '{print $1}')"
  log_msg "Sending GET /?hs=true&p=1.2&c=zom&v=0.1&u=$(audioscrobbler_urlencode ${username})&t=${tstamp}&a=${authtoken} HTTP/1.1" 2>/dev/null

  ret="$(wget -q -O - --header 'Accept-Charset: utf-8' http://$handshake_host[$site]/\?hs=true\&p=1.2\&c=zom\&v=0.1\&u=$(audioscrobbler_urlencode ${username})\&t=${tstamp}\&a=${authtoken})"
  response=(${(f)ret})

  local rstatus=${response[1]}
  case "$rstatus" in
    (OK)
    sessionid[$site]="${response[2]/
(#e)/}"
    npurl[$site]="$response[3]"
    submiturl[$site]="$response[4]"
    ;;
    (BANNED)
    status_msg "Client is banned.  Try getting a newer version at http://zomg.alioth.debian.org/"
    exit 1
    ;;
    (BADAUTH)
    status_msg "Bad authentication.  Check your credentials in $zomgconfdir/conf"
    exit 1
    ;;
    (BADTIME)
    status_msg "Time mismatch.  Check your system clock."
    exit 1
    ;;
    (FAILED *)
    status_msg "FAILURE."

    status_msg $rstatus
    return 1
    ;;
    (*)
    status_msg "$rstatus what the fuck"
    print '{{{'
    print -l ${response}
    print '}}}'
    return 1

    ;;
  esac

  as_cache_credentials "$site" "$username" "$sessionid[$site]" "$npurl[$site]" "$submiturl[$site]"
}

as_cache_credentials() {
  status_msg "Caching credentials for $2 @ $1..."
  cat >$zomgdatadir/ascreds.${1}.${2} <<EOF
sessionid[$1]="${3}"
npurl[$1]="${4}"
submiturl[$1]="${5}"
EOF

}

as_validate_handshake() {
  local credfile
  credfile=( $zomgdatadir/ascreds.${1}.${2}(Nmm-30) )
  if [[ -f $zomgdatadir/ascreds."$1"."$2" ]] && [[ -n $credfile ]];
  then
    status_msg "Refreshing credentials for $2 @ $1..."
  else
    status_msg "Handshaking for $2 @ $1..."
    audioscrobbler_handshake "$@" || return 1
  fi

  source $zomgdatadir/ascreds."${1}.${2}"
  return 0
}

as_invalidate_handshake() {
  status_msg "Invalidating credentials for $2 @ $1."
  rm -f $zomgdatadir/ascreds."${1}.${2}"
}

audioscrobbler_urlencode() {
  if (( $+options[multibyte] )); then
    setopt localoptions extendedglob nomultibyte
  else
    setopt localoptions extendedglob
  fi

  input=( ${(s::)1} )
  print -- ${(j::)input//(#b)([^A-Za-z0-9_.!*\'\(\)-])/%$(([##16]#match))}
}

audioscrobbler_constructauthtoken() {
  local password=$1
  local cr="$(print -n "${password}" | md5sum | awk '{print $1}')${challenge}"
  local challengeresponse="$(print -n "${cr}" | md5sum | awk '{print $1}')"

  print $challengeresponse
}

audioscrobbler_construct_np_query() {
  local username=$(audioscrobbler_urlencode "$1") #unused
  local sid="$2"
  local artist=$(audioscrobbler_urlencode "$3")
  local track=$(audioscrobbler_urlencode "$4")
  local album=$(audioscrobbler_urlencode "$5")
  local mbid=$(audioscrobbler_urlencode "$6")
  local length=$(audioscrobbler_urlencode "$7")
  local ttime=$(audioscrobbler_urlencode "$8") #unused
  # need tracknum

  reply=("&s=${sid}" "&a=${artist}&t=${track}&b=${album}&l=${length}&n=${tracknum}&m=${mbid}")
}

audioscrobbler_np_submit() {
  local site="$1"
  local poststr="$2"
  local username="$3"
  local conlen=$(( $#poststr + 2 ))
  local sstatus

  if (( submit[$site] == 1 ));
  then

    log_msg "connecting to np submission site ${np_submithost[$site]}:${np_submitport[$site]}"

    sstatus=$(wget -q -O - --header 'Accept-Charset: utf-8' --post-data=$poststr http://$np_submithost[$site]:$np_submitport[$site]/${np_submitcgi[$site]})

    log_msg "Status: $sstatus"

    case "$sstatus" in
    (OK)
    ;;
    (BADSESSION)
    status_msg "BADSESSION"
    as_invalidate_handshake "$site" "$username"
    ;;
    (*)
    submit[$site]=0
    status_msg "FAILED ($sstatus)"
    return 8
    ;;
    esac
  else
    return 9
  fi
}

audioscrobbler_constructquery() {
  local sid="$1"
  local artist=$(audioscrobbler_urlencode "$2")
  local track=$(audioscrobbler_urlencode "$3")
  local album=$(audioscrobbler_urlencode "$4")
  local mbid=$(audioscrobbler_urlencode "$5")
  local length=$(audioscrobbler_urlencode "$6")
  local ttime=$(audioscrobbler_urlencode "$7")
  local source="$8"
#need tracknum

  reply=("&s=${sid}" "&a[0]=${artist}&t[0]=${track}&i[0]=${ttime}&o[0]=${source}&r[0]=&l[0]=${length}&b[0]=${album}&n[0]=${tracknum}&m[0]=${mbid}")
}

audioscrobbler_submit() {
  local site="$1"
  local poststr="$2"
  local username="$3"
  local conlen=$(( $#poststr + 2 ))
  local -a response
  local ret sstatus

  if (( submit[$site] == 1 ));
  then

    log_msg "connecting to submission site ${submithost[$site]}:${submitport[$site]}"

    ret="$(wget -q -O - --header 'Accept-Charset: utf-8' --post-data=$poststr http://$submithost[$site]:$submitport[$site]/${submitcgi[$site]})"
    response=(${(f)ret})
    sstatus=${response[1]}
# INTERVAL might be under this

    log_msg "Status: $sstatus"
    case "$sstatus" in
	(OK) ;;
	(BADSESSION)
          status_msg "BADSESSION"
          as_invalidate_handshake "$site" "$username"
	  return 8
         ;;
        (*)
      submit[$site]=0
      status_msg "FAILED ($sstatus)"
      as_invalidate_handshake "$site" "$username"
      return 9
        ;;
     esac
  else
    return 10
  fi
 }
