#!/bin/sh
# tmww plugin: crime
# whatis: operations on public GM logs
# conflicts: -
# depends: -
# recommends: watch.plugin, alts.plugin or server.plugin - require dbplayers.jsonl

# this file is part of tmww - the mana world watcher
# willee, 2012-2014
# GPL v3

# check if not run as plugin
if [ "$TMWW_PLUGINS" != "yes" ] ; then
   echo >&2 "This script is tmww plugin and rely heavily on it's facilities."
   exit 1
fi

help_crime() {
   cat << EOF
crime -- operations on public GM logs

Options:
   -u -- mirror GM logs folder
   -m -- cut readable messages
   -r -- parse logs for ban/block records
   -f -- fill up player records with ban/block results
   -a -- fill up exposed char ids to altsdb
   -A -- print found char ids
   -b -- GM stats for bans (cumulative with -B)
   -B -- GM stats for blocks (cumulative with -b)
   -c -- clean database marks (e.g. to refill upgraded players DB)
   -p PLAYER -- search marks for PLAYER chars
EOF
}

[ "$TMWW_PLUGINHELP" = "yes" ] && help_crime && return 0
[ "$TMWW_PLUGINEXPORT" = "yes" ] && return 0

TMWW_CRIMEPATH="${TMWW_CRIMEPATH:-${HOME}/log/gm/}"
TMWW_CRIMEPATH="${TMWW_CRIMEPATH}/${servername}"

TMWW_CRIMELOCK="${TMWW_LOCK}/tmww-crime-${servername}"

set_crime_lock() {
   check_lock "crime" "${TMWW_CRIMELOCK}" 120
}

unset_crime_lock() {
   rmdir "${TMWW_CRIMELOCK}" 2>/dev/null
}

#
# options parser
#
#

crime_update=
crime_messages=
crime_records=
crime_fill=
crime_alts=
crime_print_alts=
crime_gmbans=
crime_gmblocks=
crime_clear=
crime_player=

OPTIND=1
while ${GETOPTS} umrfaAbBcp: opt ; do
   case "${opt}" in
       u)  crime_update=1 ;;
       m)  crime_messages=1 ;;
       r)  crime_records=1 ;;
       f)  crime_fill=1 ;;
       a)  crime_alts=1 ;;
       A)  crime_print_alts=1 ;;
       b)  crime_gmbans=1 ;;
       B)  crime_gmblocks=1 ;;
       c)  crime_clear=1 ;;
       p)  crime_player="${OPTARG}" ;;
   esac
done

if [ -n "${crime_player}" ]; then
   # feel free to override to server.plugin in config
   requireplugin alts.plugin || return 1
   func_player_show chars by player "${crime_player}" | ${AWK} ${AWKPARAMS} -- '
       NR==FNR { c[$0]=1; m=1; next }
       !m { exit }
       { for (i in c) if (index(substr($0,index($0," : ")),i)) { print; next } }
       ' - "${TMWW_CRIMEPATH}/records/bans."* "${TMWW_CRIMEPATH}/records/blocks."*
fi

if [ -n "${crime_update}" ]; then
   set_crime_lock
   (
       mkdir -p "${TMWW_CRIMEPATH}"
       cd "${TMWW_CRIMEPATH}"
       wget -c -r -N -nH --cut-dirs=1 -A 'gm.log.*' -X '*/*' -np -l 0 \
           ${servername}/gm >/dev/null 2>&1
   )
   unset_crime_lock
fi

if [ -n "${crime_messages}" ]; then
   set_crime_lock
   (
       cd "${TMWW_UTILPATH}"
       LOGPATH="${TMWW_CRIMEPATH}" make -ef gmlog.makefile messages
   )
   unset_crime_lock
fi

if [ -n "${crime_records}" ]; then
   set_crime_lock
   (
       cd "${TMWW_UTILPATH}"
       LOGPATH="${TMWW_CRIMEPATH}" make -ef gmlog.makefile records
   )
   unset_crime_lock
fi

if [ -n "${crime_clear}" ]; then
   set_crime_lock
   rm -rf "${TMWW_CRIMEPATH}"/dbupdate/*
   unset_crime_lock
fi

if [ -n "${crime_fill}" ]; then
   # feel free to override to server.plugin in config
   requireplugin alts.plugin || return 1
   set_crime_lock
   (
       cd "${TMWW_UTILPATH}"
       LOGPATH="${TMWW_CRIMEPATH}" make -ef gmlog.makefile dbupdate
   ) | sort -u | sed 's/'\''/'\''"'\''"'\''/g' | while read -r line; do
           pname=$( aux_player_get_by_char "${line}" )
           [ -n "${pname}" ] && {
               printf >&2 "Found %s as char %s\n" "${pname}" "${line}"
               printf "%s\n" "${pname}"
           }
       done | sort -u | while read -r player; do
           echo Adding "${player}"
           func_player_add "${player}" crime value true
       done
   unset_crime_lock
fi

# valid line
# [2013-10-11 13:07:56] 001-1(37,69) Melkior GM(2229419) : @hugo
# legacy format
# [2009-06-01 00:06:47] 009-1.gat(50,36) MasterKenobi : @charstats kook
# there's whole range of malformed lines (about 10 or more)
# on themanaworld.org server like:
# [2013-10-11 13:08:01] 018-3(93,98) Melkior [2013-10-11 19:20:33] 009-2(125,46) Prsm(2102937) : @invisible
# [2013-09-29 14:[2013-09-29 16:32:07] 018-2(42,24) Prsm(2102937) : @invisible
# which should be cut manually from db on first run

# WARNING:  because of ambiguous gm log format anyone can flood chardb.
#           if it happened it's recommended to switch to -A option with
#           filtering results by hand; -A option uses same stamps as -a

if [ -n "${crime_alts}" ]; then
   # makes sense only with alts.plugin
   requireplugin alts.plugin || return 1

   merge_file="${TMWW_PRIVTMP}/charmerge"
   set_crime_lock
   (
       cd "${TMWW_UTILPATH}"
       LOGPATH="${TMWW_CRIMEPATH}" make -ef gmlog.makefile altsupdate
   ) | uniq | sort | uniq > "${merge_file}"
   func_char_merge "${merge_file}"
   rm -f "${merge_file}"
   unset_crime_lock
fi

if [ -n "${crime_print_alts}" ]; then
   # makes sense only with alts.plugin
   requireplugin alts.plugin || return 1

   set_crime_lock
   (
       cd "${TMWW_UTILPATH}"
       LOGPATH="${TMWW_CRIMEPATH}" make -ef gmlog.makefile altsupdate
   ) | uniq | sort | uniq
   unset_crime_lock
fi

if [ -n "${crime_gmbans}" -o -n "${crime_gmblocks}" ]; then
   {
       [ -n "${crime_gmbans}" ] && \
           sed ${ESED} 's/^[^ ]+ [^ ]+ [^ ]+ ([^(:]+).*/\1/;s/ *$//' \
           "${TMWW_CRIMEPATH}/records/bans."*
       [ -n "${crime_gmblocks}" ] && \
           sed ${ESED} 's/^[^ ]+ [^ ]+ [^ ]+ ([^(:]+).*/\1/;s/ *$//' \
           "${TMWW_CRIMEPATH}/records/blocks."*
   } | sort | uniq -c | sort -rn | ${TMWW_UTILPATH}/bars
fi

return 0