#!/bin/bash

###########################################################
## Copyright (c) 2019-2024 Alexey Kuryakin daqgroup@mail.ru
###########################################################

###########################################################
## DIM Configurator tool for CRW-DAQ.
###########################################################

###########################################################
source $(crwkit which crwlib_base.sh); # Use base library #
source $(crwkit which crwlib_file.sh); # Use file library #
###########################################################

let abort_notify_uses=0;

###############
# print version
###############
function print_version(){
 local name="$1";
 echo "$name version 1.2";
};

###################
# print help screen
###################
function print_help(){
 local name="$1";
 print_version $name;
 echo "DIM Configurator tool for CRW-DAQ.";
 echo "Copyright (c) 2019-2024 Alexey Kuryakin daqgroup@mail.ru";
 echo "Help on $name:";
 echo " ====================> Syntax:";
 echo "  $name [Options] Command Arguments";
 echo " ====================> Options:";
 echo "   --               => options ending, next is params";
 echo "   -h,--help        => print this help screen and exit";
 echo "   --version        => print program version and exit";
 echo "   -n,--new         => new line, to separate instructions";
 echo "   -n               => option uses to process passed arguments";
 echo "                       and then start new declaration from scratch";
 echo " ====================> Arguments:";
 echo "   Command          => dic_info, dis_info, dic_cmnd, dis_cmnd, tag, end,";
 echo "                       devmsg, devsend, devpost, devsendmsg, devpostmsg,";
 echo "                       section, [], echo, print, polling, filling,";
 echo "                       help, hint, note";
 echo "   dic_info INFO/CLIENT         - declare info client service";
 echo "   dis_info INFO/SERVER         - declare info server service";
 echo "   dic_cmnd CMND/CLIENT         - declare cmnd client service";
 echo "   dis_cmnd CMND/SERVER         - declare cmnd server service";
 echo "   tag TAG1 TAG2 ..             - declare tag(s)";
 echo "   devmsg &DEMO @Update ..      - declare device message send";
 echo "   devsend &DEMO @Update ..     - declare device message send";
 echo "   devpost &DEMO @Update ..     - declare device message post";
 echo "   devsendmsg &DEMO @Update ..  - declare device message send";
 echo "   devpostmsg &DEMO @Update ..  - declare device message post";
 echo "   echo or print msg            - print or echo message msg";
 echo "   help,hint,note msg           - declare help, hint, note";
 echo "   polling mode                 - declare polling mode";
 echo "   filling data                 - declare filling data";
 echo "   section xxx                  - declare section [xxx]";
 echo "   [] or end                    - declare end of section, i.e. []";
 echo " ====================> Exit Code:";
 echo "  Return 0 on success, otherwise return error code";
 echo " ====================> Examples:";
 echo "  $name --help";
 echo "  $name --version";
 echo "  $name section DEMO -n print param = 1 -n end";
 echo "  $name dis_info DEMO/ABC -n tag ABC -n devpost \"&DemoCtrl @Update=ABC\" -n end ";
};

##########################
# program data and options
##########################
declare -i argnum=0;
declare -a args=();
declare cmnd="";

##################
# Program routines
##################

##################
# declare tag list
##################
function declare_tag(){
 if word_is_in_list "$(lower_case "$1")" "tag"; then
  shift; # skip tag itself
  while [ -n "$1" ]; do
   echo "tag $1";
   shift;
  done;
 fi;
};

################################
# adjust string s to section [s]
################################
function adjust_section(){
 local s="$1";
 s="$(echo "$s" | xargs)"; # trim spaces
 if [ "${s:0:1}"   != "[" ]; then s="[$s"; fi;
 if [ "${s: -1:1}" != "]" ]; then s="$s]"; fi;
 echo "$s";
};

######################
# declare section name
######################
function declare_section(){
 if word_is_in_list "$(lower_case "$1")" "section"; then
  adjust_section "$2";
 fi;
};

######################
# declare service name
######################
function declare_service(){
 local cmnd="$1"; local upcmnd="$(upper_case "$cmnd")"; local locmnd="$(lower_case "$cmnd")";
 local name="$2"; local upname="$(upper_case "$name")"; local loname="$(lower_case "$name")";
 echo "[&DimSrv.ServiceList]";
 echo "$upcmnd:$upname = $locmnd $name";
 echo "[$upcmnd:$upname]";
}

########################
# declare devMsg message
########################
function declare_devmsg(){
 case $(lower_case "$1") in
  devmsg)     echo -n "devMsg "; ;;
  devsend)    echo -n "devSend "; ;;
  devpost)    echo -n "devPost "; ;;
  devsendmsg) echo -n "devSendMsg "; ;;
  devpostmsg) echo -n "devPostMsg "; ;;
  *)          echo -n "$1 "; ;;
 esac;
 shift;
 echo "$@";
};

#######################
# print arguments as is
#######################
function print_asis(){
 echo "$@";
};

#######################
# print msg or echo msg
#######################
function print_echo(){
 shift; echo "$@";
};

######################
# declare end, i.e. []
######################
function declare_end(){
 echo "[]";
};

##################################
# use expression assert_args $1 $*
# to check $* has $1 args at least
##################################
function assert_args(){
 local n=$1; shift;
 if [ $# -lt $n ]; then
  abort 1 "Error: Not enough arguments specified. See --help.\nArguments: ${args[*]}";
 fi;
};

##################
# handle arguments
##################
function handle_args(){
 if [ -n "$1" ]; then
  let argnum++;
  local arg="$1";
  args+=("$arg");
  cmnd="${args[0]}";
 fi;
};

############################
# process command/arguments,
# then clear (cmnd) & (args)
############################
function process_cmnd_args(){
 if [ -n "$cmnd" ]; then
  case $(lower_case "$cmnd") in
   tag)                                          assert_args 2 "${args[@]}"; declare_tag     "${args[@]}"; ;;
   []|end)                                       assert_args 1 "${args[@]}"; declare_end     "${args[@]}"; ;;
   section)                                      assert_args 2 "${args[@]}"; declare_section "${args[@]}"; ;;
   echo|print)                                   assert_args 1 "${args[@]}"; print_echo      "${args[@]}"; ;;
   polling|filling|help|note|hint)               assert_args 1 "${args[@]}"; print_asis      "${args[@]}"; ;;
   dic_info|dis_info|dic_cmnd|dis_cmnd)          assert_args 2 "${args[@]}"; declare_service "${args[@]}"; ;;
   devmsg|devsend|devpost|devsendmsg|devpostmsg) assert_args 2 "${args[@]}"; declare_devmsg  "${args[@]}"; ;;
   *)                                            abort 1 "Error: unknown command $cmnd. See --help."; ;;
  esac;
 fi;
 cmnd="";
 args=();
};

################
# main processor
################
function main(){
 ######################
 # command line parsing
 ######################
 if [ $# -lt 1 ]; then
  abort 2 "Error: No arguments. See --help.";
 fi;
 local opt="";
 local isopt=1;
 for i in $(seq $#); do
  local arg="$1"; shift;
  if is_option "$arg" && [ $isopt -eq 1 ] && [ -z "$opt" ]; then
   case $arg in
    --)        isopt=0; ;; # marker of options end
    --version) print_version $scriptname; exit 0; ;;
    -h|--help) print_help    $scriptname; exit 0; ;;
    -n|--new)  process_cmnd_args;  opt=""; ;;
    *)         handle_args "$arg"; opt=""; ;;
   esac;
  else
   case $opt in
    '')        handle_args "$arg"; ;;
    *)         abort 1 "Error: unknown option $opt. See --help."; ;;
   esac;
   opt="";
  fi;
 done;
 ################
 # Task execution
 ################
 process_cmnd_args;
 return 0;
};

main "$@";

##############
## END OF FILE
##############
