#!/bin/bash
#
# sccl_show_cluster listet alle Pakete im Script-Cluster auf
#
# Aufruf:
#
# sccl_show_cluster [-a] [-F] [-l|-L] [-v] [-V] [<groups> ...]
#
#
########################################################################################
#
MYPRG="sccl ${0##*/sccl_}"
#
unset FQDN VERB FULL VERSION SHOWMASTER SHOWGROUPNAMES SHOWERRORS LONGNAMES
while getopts eGaFlLmvV? op; do
  case "$op" in
   e) SHOWERRORS=1;;
   G) SHOWGROUPNAMES='-g';;
   a) FULL=1;;
   F) FQDN=1;;
   l) LONGNAMES=1;;
   L) LONGNAMES=2;;
   m) SHOWMASTER=1;;
   v) VERB=1;;
   V) VERSION=1;;
   *) echo "usage: $MYPRG [-a] [-e] [-F] [-G] [-l|-L] [-m] [-v] [-V] [<groups> ...]
  -a show all groups
  -e show start or stop errors
  -F show FQDN
  -G show groupnames
  -l show long packagenames
  -L only long packagenames
  -m show master
  -v add description
  -V show versions"
      exit 0;;
  esac
done
#
shift $(( $OPTIND - 1))
#
SHOWGROUPS="$@"
#
. $(dirname $0)/globals.settings
#
if [[ -n "$FULL" ]]; then
  MYNODES="$NODES"
fi
#
if [[ ! -f $PACKAGES && -z "$VERB$VERSION$SHOWMASTER" ]]; then
  echo "Clustername: $CLUSTER"
  echo "Clusternodes: $NODES"
  exit 1
fi
#
{ for n in $MYNODES; do
    echo "N $n"
  done | sort
  for n in $MYNODES; do
    ((./sccl_list_packages_on_node -s $n || echo "? $n") | sed "s/^\([^?]\)/A $n \1/")&
  done
  if [[ -n "$VERSION" || -n "$SHOWMASTER" ]]; then
    for n in $MYNODES; do
      (./sccl_node -v${SHOWMASTER/*/m} $n | sed "/^usage: /d;s/^/V $n /")&
    done
  fi
  if [[ -n "$LONGNAMES" ]]; then
    { [[ -r $RESOURCES ]] && cat $RESOURCES || ./sccl_read_config RESOURCES
    } | awk '$1 !~ /^[#]|^[[:blank:]]*$/ {print "R", $0}'
  fi
  if [[ -n "$FULL" ]]; then
    if [[ -n "$SHOWGROUPNAMES" ]]; then
      { [[ -r $PACKAGES ]] && cat $PACKAGES || ./sccl_read_config PACKAGES
      } | awk '$1 !~ /^[#]|^[[:blank:]]*$/ {print "P", $0}'
    else
      { [[ -r $PACKAGES ]] && cat $PACKAGES || ./sccl_read_config PACKAGES
      } | awk '$1 !~ /^[[#]|^[[:blank:]]*$/ {print "P", $0}' $PACKAGES
    fi
  else
    ./sccl_my_packages $SHOWGROUPNAMES | sed 's/^/P /'
  fi
  if [[ -n "$SHOWERRORS" ]]; then
    for n in $MYNODES; do
      (./sccl_get_errors $n | sed "s/^/E |$n|/")&
    done
  fi
  wait
  { [[ -r $RESOURCES ]] && cat $RESOURCES || ./sccl_read_config RESOURCES
  } | awk '$3 == "EXECUTE" {print "X", $0}'
} | awk -v longnames=$LONGNAMES -v CLUSTER="$CLUSTER" -v FQDN="$FQDN" -v SHOWMASTER="$SHOWMASTER" -v VERSION="$VERSION" '
BEGIN { ln = 8
        nn = 0
        if( length(CLUSTER) > 8 )
          lp = length(CLUSTER)
        else
          lp = 8
        np = 0
        grp = ""
      }
$1 == "X" { execute[$2] = 1 }
$1 == "V" { version[$2] = $3
            master[$2] = $4
          }
$1 == "N" { nfqdn[nn] = $2
            if( FQDN )
              l = length(n[nn++] = $2)
            else
              l = length(n[nn++] = gensub("[.].*", "", 1, $2))
            if( l > ln )
              ln = l
          }
$1 == "A" { if( $4 ~ /[Rs!]/ )
              npa[$2":"$3] = 1
            if( $4 == "S" )
              npas[$2":"$3] = "s"
            else if( $4 ~ /[ersNBD!E]/ )
              npas[$2":"$3] = $4
          }
$1 == "R" { lnms[$2] = $3 }
$1 == "P" { if( $2 ~ "^[[]" )
              grp = $2
            else
            { g[np] = grp
              if( longnames == 1 )
                pdisp[np] = $2 " " lnms[$2]
              else if( longnames == 2 )
                pdisp[np] = lnms[$2]
              else
                pdisp[np] = $2
              if( length(pdisp[np]) > lp )
                lp = length(pdisp[np])
              p[np++] = $2
              if( $3 == "+" )
                npp[$2] = 1
              else if( $3 != "-" )
              { j = split($3, a, ",")
                for( i = 1; i <= j; i++ )
                  nps[a[i]":"$2] = 1
              }
              for( i = 4; i <= NF; i++ )
              { j = split($i, a, ",")
                for( k = 1; k <= j; k++ )
                  npe[a[k]":"$2] = 1
              }
            }
          }
$1 == "E" { split($0, a, "|")
            if( nerr[a[3]] )
            { err[a[3]] = nerr[a[3]] ": " err[a[3]] ", " a[2] ": " a[4]
              nerr[a[3]] = ""
            }
            else if( err[a[3]] )
              err[a[3]] = err[a[3]] ", " a[2] ": " a[4]
            else
            { err[a[3]] = a[4]
              nerr[a[3]] = a[2]
            }
          }
$1 == "?" { offline[$2] = 1 }
END { printf("%-*s", lp, toupper(CLUSTER));
      lz = lp
      for( i = 0; i < nn; i++ )
      { printf(" %-*s", ln, n[i])
        lz += ln+1
      }
      printf("\n")
      if( SHOWMASTER )
      { printf("%-*s", lp, "")
        for( i = 0; i < nn; i++ )
          printf("     %-*s", ln-4, master[nfqdn[i]])
        printf("\n")
      }
      if( VERSION )
      { printf("%-*s", lp, "")
        for( i = 0; i < nn; i++ )
          printf("   %-*s", ln-2, version[nfqdn[i]])
        printf("\n")
      }
      for( i=0; i < lz; i++ )
        printf("-")
      printf("\n")
      for( j = 0; j < np ; j++ )
      { printf("%-*s", lp, pdisp[j])
        for( i = 0; i < nn; i++ )
        { if( offline[n[i]] )
          { if( npa[nfqdn[i]":"p[j]] == 1 || nps[nfqdn[i]":"p[j]] == 1 || npe[nfqdn[i]":"p[j]] == 1 )
              printf("     %-*s", ln-4, "?")
            else
              printf(" %*s", ln, "")
          }
          else if( npa[nfqdn[i]":"p[j]] == 1 )
            printf("     %-*s", ln-4, "R" npas[nfqdn[i]":"p[j]])
          else if( nps[nfqdn[i]":"p[j]] == 1 )
          { if( execute[p[j]] )
              printf("     %-*s", ln-4, ";" npas[nfqdn[i]":"p[j]])
            else
              printf("     %-*s", ln-4, "-" npas[nfqdn[i]":"p[j]])
          }
          else if( npe[nfqdn[i]":"p[j]] == 1 )
          { if( execute[p[j]] )
              printf("     %-*s", ln-4, "," npas[nfqdn[i]":"p[j]])
            else if( npp[p[j]] )
              printf("     %-*s", ln-4, "+" npas[nfqdn[i]":"p[j]])
            else
              printf("     %-*s", ln-4, "." npas[nfqdn[i]":"p[j]])
          }
          else
            printf(" %*s", ln, "")
        }
        if( err[p[j]] )
          printf(" %s\n", err[p[j]])
        else
          printf("\n")
        if( g[j] )
          print g[j]
        for( i=0; i < lz; i++ )
          printf("-")
        printf("\n")
      }
    }
'
if [[ -n "$VERB" ]]; then
  cat <<EOF

 -  : not running, start on startup
 .  : not running, allowed to start
 +  : not running, start on last node
 ;  : not running, execute on startup
 ,  : not running, allowed to execute
 *s : starting (* = [-.+])
 *r : starting after SETSTATE (* = [-.+])
 *t : running testpackage (* = [-.+])
 *e : executing (* = [;,])
 *E : error on starting or executing package (* = [-.+;,])
 R  : running
 Rs : stopping
 R! : error on stopping package
  N : Node stopped
  B : Node booting
  D : Node disabled
  ? : no connection
EOF
fi
