#!/bin/bash

##########################################################
# Copyright (c) 2001-2025 Alexey Kuryakin daqgroup@mail.ru
##########################################################
# CrwKit script to run useful DaqGroup's "cherry" scripts.
##########################################################

################################
# Current script identification.
################################
readonly startupdir="$(pwd -LP)";
readonly scriptfile="${BASH_SOURCE[0]}";
readonly scriptname="$(basename $scriptfile)";
readonly scriptbase="$(basename $scriptfile .sh)";
readonly scripthome="$(dirname  $scriptfile)";
readonly scriptFILE="$(realpath $scriptfile)";
readonly scriptHOME="$(dirname  $scriptFILE)";

readonly column_width=80;
readonly cherry_lawns="$scriptHOME /mnt/data/root/scripts";
declare -a zen_items=(); # zenity menu items
readonly home_hosts="y510p";

#############################################################################################################################
# https://stackoverflow.com/questions/1763891/is-it-possible-to-make-stdout-and-stderr-output-be-of-different-colors-in-xterm
#############################################################################################################################
function colorize_norm()( set -o pipefail; ( "$@" 2>&1>&3 | sed $'s,.*,\e[31m&\e[m,'   >&2 ) 3>&1 | sed $'s,.*,\e[32m&\e[m,'   );
function colorize_bold()( set -o pipefail; ( "$@" 2>&1>&3 | sed $'s,.*,\e[1;31m&\e[m,' >&2 ) 3>&1 | sed $'s,.*,\e[1;32m&\e[m,' );
function colorize_head()( set -o pipefail; ( "$@" 2>&1>&3 | sed $'s,.*,\e[1;35m&\e[m,' >&2 ) 3>&1 | sed $'s,.*,\e[1;37m&\e[m,' );
function colorize_none()( "$@"; );

function note(){ return 0; };
function ignore(){ return 0; };

##################################
# Uses language dependent strings?
##################################
declare -i uses_langstr=1;

################################
# Language dependent string echo
# langstr en 'Hello' ru 'Привет'
################################
function langstr(){
 local lng="en"; local msg="";
 if [[ "$uses_langstr" = "1" ]]; then lng="${LANG:0:2}"; fi;
 while [[ -n "$lng" ]] && [[ -n "$1" ]] && [[ -n "$2" ]]; do
  if [[ "$lng" = "$1" ]]; then msg="$2"; break; fi;
  if [[ "$lng" = "en" ]]; then msg="$2"; fi;
  if [[ "$lng" = "us" ]]; then msg="$2"; fi;
  if [[ "$lng" = "uk" ]]; then msg="$2"; fi;
  shift; shift;
 done;
 if [[ -n "$msg" ]]; then echo "$msg"; fi;
};

function do_version(){
 echo "$scriptname version 1.0";
};

function do_help(){
 colorize_head echo "########################################################";
 colorize_none echo "Copyright (c) 2001-2024 Alexey Kuryakin daqgroup@mail.ru";
 colorize_bold echo "CrwKit script to run useful DaqGroup\`s \"cherry\" scripts.";
 colorize_head echo "Usage:";
 colorize_bold echo " crwkit cherry [-options] [arguments]";
 colorize_head echo "Options:";
 colorize_norm echo " -h,--help      - show help";
 colorize_norm echo " --version      - show version";
 colorize_norm echo " -l,--list      - list cherry script files";
 colorize_norm echo " -m,--menu      - cherry menu with zenity";
 colorize_norm echo " -z,--zen       - cherry menu with zenity";
 colorize_head echo "Arguments:";
 colorize_bold echo " command [parameters]";
 colorize_norm echo " where command is one of listed:";
 colorize_none print_cherry_table;
 colorize_head echo "Examples:";
 colorize_norm echo " crwkit cherry firefox-backup";
 colorize_head echo "########################################################";
};

################################
# print $1 to stderr without EOL
################################
function print_stderr(){
 1>&2 echo -ne "$1";
};

##############################
# fatal error message and exit
##############################
function fatal(){
 if [[ -t 1 ]] && [[ -t 2 ]]; then
  colorize_bold print_stderr "\n\n$2\n\n";
 else
  print_stderr "\n\n$2\n\n";
 fi;
 exit $1;
};

function is_home_host(){
 for host in $home_hosts; do
  if [[ "$host" = "$(hostname)" ]]; then return 0; fi;
 done;
 return 1;
};

function screen_size(){
 local size="$(xrandr | grep ' connected primary' | sed -e 's/.* primary\s*//' -e 's/[+\-].*//' -e 's/x/ /')";
 if [[ -n "$size" ]]; then echo "$size"; else echo "800 600"; fi;
};

function screen_width(){
 screen_size | cut -d' ' -f1;
};

function screen_height(){
 screen_size | cut -d' ' -f2;
};

#################################
# find *.sh files in directory $1
#################################
function find_sh_files_in_dir(){
 local dir="$1";
 if [[ -d "$dir" ]]; then
  find "$dir" -follow -type f -and -executable -and -name '*.sh' -and -not -path '*/.*';
 fi;
};

##########################
# unsorted raw cherry list
##########################
function raw_cherry_list(){
 for lawn in $cherry_lawns; do
  if [[ -d $lawn ]]; then
   find_sh_files_in_dir "$lawn" | xargs -I {} basename {} .sh | sed 's/^/  /';
  fi;
 done;
};

###################################
# print sorted cherry list as table
###################################
function print_cherry_table(){
 raw_cherry_list | grep -v "\b$scriptbase\b" | sort | uniq | column -s ' ' -c $column_width;
};

#########################################
# get formatted list of cherry : filepath
#########################################
function list_cherry_files(){
 local -i len=0;
 for berry in $(print_cherry_table | xargs); do
  local l="${#berry}"; if [[ $l -gt $len ]]; then let len=$l; fi;
 done; 
 for berry in $(print_cherry_table | xargs); do
  printf "%-*s : %s\n" "$len" "$berry" "$(find_cherry "$berry" "$cherry_lawns")";
 done;
};

########################
# cherry: command to run
# find cherry by name $1
# in directories list $2
########################
function find_cherry(){
 if [ $# -eq 2 ]; then
  local berry="$(basename "$1" .sh)";
  for dir in $2; do
   for fruit in $(find "$dir" -follow -type f -and -executable -and -name "$berry.sh" -and -not -path '*/.*'); do
    local cherry="$(realpath "$fruit")";
    if [[ -f "$cherry" ]] && [[ -x "$cherry" ]]; then
     echo "$cherry";
     return 0;
    fi;
   done;
  done;
 fi;
 return 1;
};

function zen_item(){
 zen_items+=( "$1" "$2" );
};
function zen_skip(){
 return 0;
};

function init_zen_menu_items(){
 local separator1="$(printf "%24s" | tr ' ' '=')";
 local separator2="$(printf "%70s" | tr ' ' '=')";
 zen_item $separator1               "$(langstr ru "ALSE Инсталляция и Настройка:" \
                                               en "ALSE Installation & Settings:")";
 zen_item alse-setup                "$(langstr ru "SETUP:    Установить стандартный набор программ." \
                                               en "SETUP:    Instal standard software tools, utils.")";
 zen_item alse-tweak                "$(langstr ru "TWEAK:    Настроить каталоги и параметры для DaqGroup." \
                                               en "TWEAK:    User directories and parameters for DaqGroup.")";
 zen_item alse-update               "$(langstr ru "UPDATE:   Проверить и обновить пакеты AstraLinux." \
                                               en "UPDATE:   Update and upgrage packages of AstraLinux.")";
 zen_item $separator1               "$(langstr ru "ALSE REPO Операции с репозиторием:" \
                                               en "ALSE REPO Operations with repository:")";
 zen_item alse-rsync-hdd-to-ufd     "$(langstr ru "HDD->UFD: Копия зеркала репозитория ALSE с Диска (HDD) на Флешку (UFD)." \
                                               en "HDD->UFD: Copy repository mirror from HardDisk (HDD) to USB/Flash (UFD).")";
 zen_item alse-sources              "$(langstr ru "SOURCES:  Выбор источника ПО (расположения репозитория)." \
                                               en "SOURCES:  Choose software sources (repository location).")";
 zen_item alse-rsync-net-to-hdd     "$(langstr ru "NET->HDD: Копировать зеркало из Локальной Сети (NET) на Диск (HDD)." \
                                               en "NET->HDD: Copy repository mirror from Network (NET) to HardDisk (HDD).")";
 zen_item alse-http-mirror          "$(langstr ru "MIRROR:   Запуск локального HTTP репозитория AstraLinux." \
                                               en "MIRROR:   Launch local HTTP mirror of AstraLinux repository.")";
 zen_item alse-rsync-ufd-to-hdd     "$(langstr ru "UFD->HDD: Копия зеркала репозитория с Флешки (UFD) на Диск (HDD)." \
                                               en "UFD->HDD: Copy repository mirror from USB/Flash (UFD) to HardDisk (HDD)")";
 zen_item $separator1               "$(langstr ru "Утилиты общего назначения:" \
                                               en "General purpose utilities:")";
 zen_item show-ls-colors            "$(langstr ru "Показать цветовую палитру команды ls." \
                                               en "Show color palette of command ls.")";
 zen_item firefox-backup            "$(langstr ru "Сохранение копии настроек FireFox." \
                                               en "Save FireFox settiongs backup copy.")";
 zen_item make-mime-types-markdown  "$(langstr ru "Запись ~/.mime.types для обзора Markdown и других файлов в Firefox." \
                                               en "Create ~/.mime.types for browse Markdown and other(s) with Firefox.")";
 if is_home_host; then
  zen_item $separator1              "$(langstr ru "Мои домашние сайты:" \
                                               en "Home working sites:")";
  zen_item smb-mount-archive        "$(langstr ru "SMB FS - Подключить  archive." \
                                               en "SMB FS - Mount  host archive.")";
  zen_item smb_umount_archive       "$(langstr ru "SMB FS - Отключить   archive." \
                                               en "SMB FS - Umount host archive.")";
  zen_item $separator1              "$(langstr ru "Обслуживание сайта crw-daq.su:" \
                                               en "Services for site crw-daq.su:")";
  zen_item ssh-mount-crw-daq-su     "$(langstr ru "SSH FS - Подключить каталог crw-daq.su." \
                                               en "SSH FS - Mount    directory crw-daq.su.")";
  zen_item ssh-umount-crw-daq-su    "$(langstr ru "SSH FS - Отключить  каталог crw-daq.su." \
                                               en "SSH FS - Unmount  directory crw-daq.su.")";
 else
  zen_item $separator1              "$(langstr ru "Наши рабочие сайты:" \
                                               en "Work service sites:")";
  zen_item ssh-mount-simply         "$(langstr ru "SSH FS - Подключить  simply." \
                                               en "SSH FS - Mount  host simply.")";
  zen_item ssh_umount_simply        "$(langstr ru "SSH FS - Отключить   simply." \
                                               en "SSH FS - Umount host simply.")";
  zen_item smb-mount-simply         "$(langstr ru "SMB FS - Подключить  simply." \
                                               en "SMB FS - Mount  host simply.")";
  zen_item smb_umount_simply        "$(langstr ru "SMB FS - Отключить   simply." \
                                               en "SMB FS - Umount host simply.")";
  zen_item smb-mount-crwbox         "$(langstr ru "SMB FS - Подключить  crwbox." \
                                               en "SMB FS - Mount  host crwbox.")";
  zen_item smb_umount_crwbox        "$(langstr ru "SMB FS - Отключить   crwbox." \
                                               en "SMB FS - Umount host crwbox.")";
 fi;
 zen_item $separator1               "$separator2";
 zen_item exit                      "$(langstr ru "Выйти (Закрыть)" en "Exit (Close)")";
 zen_item $separator1               "$separator2";
};

function cherry_note(){
 return;
 case $1 in
  '') ;;
  astra-download-mirror)    langstr ru "Загрузка зеркала репозитория AstraLinux из Интернета на HDD." \
                                    en "Download mirror of AstraLinux repository from Internet to HDD."; ;;
  *)                        langstr ru "Утилита $1" \
                                    en "Utility $1"; ;;
 esac;
};

function do_zen(){
 local args=();
 local -i sy=680;
 local -i symax=600;
 let symax=$(screen_height)-200;
 if [[ $symax -lt 600 ]]; then let symax=600; fi;
 if [[ $sy -gt $symax ]]; then let sy=$symax; fi;
 local title="$(langstr ru "Пуск утилиты DaqGroup Cherry:" en "Run DaqGroup Cherry Utility:")";
 local rem1="<span size='x-small'><b>ALSE</b> = <i>Astra Linux Special Edition</i></span>";
 local remark="$(langstr ru "<span fgcolor='blue' size='small'><b>Примечание:</b></span> $rem1" \
                         en "<span fgcolor='blue' size='small'><b>Remark:</b></span> $rem1")";
 local util="<span color='green'>DaqGroup</span> <span color='red'>Cherry</span>";
 local text="<big><b>$(langstr ru "Выбирите утилиту $util для запуска:" en "Choose $util utility to run:")</b></big>\n$remark";
 local winicon="$(realpath $scriptHOME/cherry.png)"; if [[ ! -f "$winicon" ]]; then winicon="question"; fi;
 args+=( --window-icon=$winicon                              ); 
 args+=( --title "$title" --text "$text"                     );
 args+=( --width 800 --height $sy                            );
 args+=( --list --print-column 1                             );
 args+=( --column "$(langstr ru "Команда" en "Command")"     );
 args+=( --column "$(langstr ru "Комментарий" en "Comment")" );
 for item in $(print_cherry_table | xargs); do
  local menu="$(cherry_note "$item")";
  if [[ -z "$menu" ]]; then continue; fi;
  if [ "$item" = "$scriptbase" ]; then continue; fi;
  args+=( "$item" "$menu" );
 done;
 init_zen_menu_items;
 while true; do
  local item="$(zenity "${args[@]}" "${zen_items[@]}" 2>/dev/null)";
  case $item in
   exit) break; ;;
   -*)   ignore; ;;
   =*)   ignore; ;;
   '')   ignore; break; ;;
   *)    handle_params "$item"; break; ;;
  esac;
 done;
};

function do_menu(){
 do_zen;
};

function smb_umount_archive(){
 local cmd="$(find_cherry "smb-mount-archive" "$cherry_lawns")";
 if [[ -n "$cmd" ]]; then
  echo unix grun xterm -hold -e $cmd -u;
  exec unix grun xterm -hold -e $cmd -u;
 fi;
};

function smb_umount_crwbox(){
 local cmd="$(find_cherry "smb-mount-crwbox" "$cherry_lawns")";
 if [[ -n "$cmd" ]]; then
  echo unix grun xterm -hold -e $cmd -u;
  exec unix grun xterm -hold -e $cmd -u;
 fi;
};

function smb_umount_simply(){
 local cmd="$(find_cherry "smb-mount-simply" "$cherry_lawns")";
 if [[ -n "$cmd" ]]; then
  echo unix grun xterm -hold -e $cmd -u;
  exec unix grun xterm -hold -e $cmd -u;
 fi;
};

function ssh_umount_simply(){
 local cmd="$(find_cherry "ssh-mount-simply" "$cherry_lawns")";
 if [[ -n "$cmd" ]]; then
  echo unix grun xterm -hold -e $cmd -u;
  exec unix grun xterm -hold -e $cmd -u;
 fi;
};

################################
# handle command line parameters
################################
function handle_params(){
 local berry="$1";
 if [[ -n "$berry" ]]; then
  local cmd="$(find_cherry "$berry" "$cherry_lawns")";
  if [[ "$(type -t $berry)" = "function" ]]; then
   if [[ -t 1 ]]; then
    shift; note "skip cmd to get arguments";
    echo $berry "$@";
    eval $berry "$@";
    exit $?;
   else
    cmd="$scriptFILE $berry";
   fi;
  fi;
  if [[ -n "$cmd" ]]; then
   shift; note "skip cmd to get arguments";
   echo unix grun xterm -hold -e $cmd "$@";
   exec unix grun xterm -hold -e $cmd "$@";
  else
   fatal 1 "Error: unknown command $berry.";
  fi;
 fi;
};

######################
# main function to run
######################
function main(){
 if [[ -n "$1" ]]; then
  case $1 in
   -h|-help|--help)    do_help; ;;
   -version|--version) do_version; ;;
   -l|-list|--list)    list_cherry_files; ;;
   -m|-menu|--menu)    do_menu; ;;
   -z|-zen|--zen)      do_zen; ;;
   -*)                 fatal 1 "Error: invalid option $1."; ;;
   *)                  handle_params "$@"; ;;
  esac;
 else
  fatal 1 "Error: missed arguments. Call $scriptname -h to get help.";
 fi;
};

main "$@";

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