#!/bin/bash
############################################################
#                                                          #
# lunar - Lunar module management utility                  #
#                                                          #
############################################################
# sorcery is part of the sorcery spell management utility  #
# Copyright 2001 by Kyle Sallee                            #
############################################################
#                                                          #
# this WAS sorcery script of a source based Linux distro,  #
# calls Sorcerer GNU/Linux, or SGL. SGL is no longer       #
# available with GPL license. Since this script was taken  #
# before licensing scheme change, no legal problems I      #
# guess.                                                   #
#                                                          #
# the code is re-written for Lunar. The previous Copyright #
# notices are kept; just in case some code is left :=)     #
# Kagan Kongar <kongar@tsrsb.org.tr>, 20020519             #
#                                                          #
############################################################
#                                                          #
# Parts Copyrighted Jason Johnston  2002 under GPLv2       #
#                                                          #
# Parts Copyrighted Kagan Kongar 2002 under GPLv2          #
#                                                          #
############################################################

help() {
  cat <<EOF
Lunar -- a menu-driven software package management utility

Example:        lunar
  This invokes the full-screen interface

Usage:		lunar [general options] [command [command parameters]]

General options:

-d  |  --debug                  Enables debug messages
-h  |  --help                   Displays this help text
-v  |  --verbose                Increases the level of message output

Commands:

prune                  Removes old sources and install/compile logs
renew                  Checks ver. against moonbase & recompiles if necessary
update                 Fetches latest moonbase and then does a "renew"
rebuild                Recompiles all installed modules
optimize               Shortcut to the optimization menu
fix                    Check and fix all modules and internal state of lunar
nofix                  Check but do not fix modules and internal state
fixdepends             Check and fix the dependency database of lunar
set  [var [value]]     Check internal variable(s) and assign their values
unset var              Unsets an internal variable
resurrect  module(s)   Force modulename(s) to be unpacked from /var/cache
install    module(s)   Install a checklist of modules
remove     module(s)   Remove a checklist of modules
hold       module(s)   Place a hold on a checklist of modules
unhold     module(s)   Remove a hold on a checklist of modules
exile      module(s)   Remove a module a/o prevent it from being resurrected
unexile    module(s)   Allows a module to be compiled|resurrected again
enforce    module(s)   Enforce optinal selection on a list of modules
unenforce  module(s)   Remove enforce  on a list of modules
EOF
  exit 1
}

show_modules() {
  for MODULE in $(list_modules "$1"); do
    if ! module_installed $MODULE &&
      ! module_exiled $MODULE; then
      (
        run_details $MODULE
        echo "$MODULE"
        echo "$VERSION"
        echo "${SHORT:-Short Description Unavailable}"
      )
    fi
  done
}

has_modules() {
  for MODULE in $(list_modules "$1"); do
    if ! module_installed $MODULE &&
      ! module_exiled $MODULE; then
      return 0
    fi
  done
  return 1
}

show_sections() {
  for SECTION in $(list_sections); do
    has_modules $SECTION && {
      echo "$SECTION"
      echo "section"
    }
  done
}

select_section() {
  $DIALOG --title "Section Selection Menu" \
    --default-item "$SECTION" \
    --ok-label "Select" \
    --cancel-label "Exit" \
    --menu \
    "" \
    0 40 15 \
    $(show_sections)
}

add_pkgs() { (
  while
    SECTION=$(select_section)
  do
    while
      SECTION_MODULES=$(show_modules $SECTION)
      MODULE=$($DIALOG --title "Select module to install please" \
        --item-help \
        --menu \
        "Section: $SECTION" \
        0 60 10 \
        $SECTION_MODULES)
    do
      SCRIPT_DIRECTORY=$MOONBASE/$SECTION/$MODULE
      DESCRIPTION=$(run_module_file $MODULE DETAILS)

      if $DIALOG --title "Install $MODULE" \
        --yesno "$DESCRIPTION" \
        14 76; then
        push_install_queue $MODULE
        $DIALOG --msgbox "$MODULE added to the install queue." 5 60
      else
        $DIALOG --msgbox "$MODULE will not be installed." 5 60
      fi
    done
  done
); }

show_file() {
  if [ -f $1 ]; then
    case $(file -b $1 | cut -d ' ' -f1) in
      bzip2 | gzip | XZ) view_file $1 ;;
      *) $DIALOG --textbox $1 10 0 ;;
    esac
  else
    $DIALOG --msgbox "File not found." 0 0
    return 1
  fi
}

file_list() {
  pushd $1 >/dev/null
  file -N -F ' ' * | cut -d ' ' -f1,3 --output-delimiter='
	'
  popd >/dev/null
}

file_menu() {
  FILE_LIST=$(file_list $1)
  echo $1/$($DIALOG --title "Please select a file." \
    --menu "" 0 0 0 \
    $FILE_LIST)
}

show_installed_modules() {
  for LINE in $(sort "$MODULE_STATUS_BACKUP"); do
    (
      MODULE=$(echo "$LINE" | cut -d : -f1)
      STATUS=$(echo "$LINE" | cut -d : -f3)
      VERSION=$(echo "$LINE" | cut -d : -f4)
      SIZE=$(echo "$LINE" | cut -d : -f5)

      # TODO THIS IS BROKEN
      if module_installed $MODULE; then
        SHORT="Short Description Unavailable"
        run_module_file $MODULE DETAILS &>/dev/null
        echo -e "$MODULE\n"
        echo -e "$VERSION,$SIZE\n"
        echo -e "\"$SHORT\"\n"
      fi
    )
  done
}

remove_pkgs() {
  while
    if [ -z "$INSTALLED_MODULES" ]; then
      INSTALLED_MODULES=$(show_installed_modules)
    fi

    unset MODULE
    MODULE=$($DIALOG --title "Select module to remove:" \
      --item-help \
      --ok-label "Select" \
      --cancel-label "Exit" \
      --menu "" 0 60 10 \
      $INSTALLED_MODULES)
  do
    (
      SECTION=$(find_section $MODULE)
      SCRIPT_DIRECTORY=$MOONBASE/$SECTION/$MODULE
      DESCRIPTION=$(run_module_file $MODULE DETAILS)

      if $DIALOG --title "Remove $MODULE" \
        --yesno "$DESCRIPTION" \
        12 76; then
        push_remove_queue $MODULE &&
          $DIALOG --msgbox "$MODULE added to the remove queue." 5 60 ||
          $DIALOG --msgbox "$MODULE is not really installed?" 5 60
      fi
    )
  done
}

make_checklist() {
  for MODULE in $(list_modules "$1"); do
    (
      run_details $MODULE

      if module_installed $MODULE; then
        STATUS="on"
      else
        STATUS="off"
      fi

      echo $MODULE
      echo $VERSION
      echo $STATUS
      echo ${SHORT:-Short Description Unavailable}
    )
  done
}

process_section() {
  KEEP_LIST=$2

  for LINE in $(list_modules "$1"); do
    if echo -e "$KEEP_LIST" |
      grep -q "^$LINE\$"; then
      push_install_queue $LINE
    else
      push_remove_queue $LINE
    fi
  done
}

select_pkgs() {
  SELECT_TITLE="Module Toggle Selection Menu"
  SELECT_HELP="[X]=install  [ ]=remove"

  while SECTION=$(select_section); do
    [ -z "$(list_modules $SECTION)" ] ||
      CHECKLIST=$(make_checklist $SECTION)

    if OUTLIST=$($DIALOG --title "$SELECT_TITLE" \
      --ok-label "Commit" \
      --item-help \
      --separate-output \
      --checklist \
      "$SELECT_HELP  $SECTION" \
      0 0 10 \
      $CHECKLIST); then
      process_section "$SECTION" "$OUTLIST"
    fi
  done
}

make_hold_checklist() {
  for LINE in $(grep -E '[:+](installed|held)[:+]' "$MODULE_STATUS_BACKUP" | sort); do
    (
      MODULE=$(echo "$LINE" | cut -d: -f1)
      STATUS=$(echo "$LINE" | cut -d: -f3)
      VERSION=$(echo "$LINE" | cut -d: -f4)
      echo "$STATUS" | grep -q -E '[:+]held[:+]' && HELD="on" || HELD="off"
      SHORT="Short description unavailable"
      if run_details $MODULE &>/dev/null; then
        echo $MODULE
        echo $VERSION
        echo $HELD
        echo $SHORT
      fi
    )
  done
}

hold_pkgs() {
  HOLD_TITLE="Select modules to hold or unhold"
  HOLD_HELP="[X]=held  [ ]=installed"

  if OUTLIST=$($DIALOG --title "$HOLD_TITLE" \
    --item-help \
    --ok-label "Commit" \
    --separate-output \
    --checklist \
    "$HOLD_HELP" \
    0 0 10 \
    $(make_hold_checklist)); then
    unhold_modules $(cut -d: -f1 "$MODULE_STATUS")
    hold_modules $OUTLIST
  fi

}

module_menu() {
  while
    U_HELP="Current software hinders crackers' attempts to infiltrate your box"
    M_HELP="Install and remove multiple modules from a section using a single selection"
    A_HELP="Simple safe, verbose way of selecting modules for installation"
    R_HELP="Simple safe, verbose way of selecting modules for removal"
    B_HELP="Rebuild all installed modules"
    H_HELP="Held modules will not be upgraded until unheld or broken"
    E_HELP="Done managing modules"
    TITLE="Module Menu"
    OK="Select"
    CANCEL="Exit"

    COMMAND=$($DIALOG --title "$TITLE" \
      --item-help \
      --ok-label "$OK" \
      --cancel-label "$CANCEL" \
      --menu "" 0 0 0 \
      "A" "Add" "$A_HELP" \
      "B" "Rebuild" "$B_HELP" \
      "H" "Hold" "$H_HELP" \
      "R" "Remove" "$R_HELP" \
      "S" "Select" "$M_HELP" \
      "U" "Update" "$U_HELP")
  do
    case $COMMAND in
      U) update ;;
      S) select_pkgs ;;
      A) add_pkgs ;;
      R) remove_pkgs ;;
      B) rebuild ;;
      H) hold_pkgs ;;
      E) break ;;
    esac
  done
}

grep_install_logs() {
  if WHAT=$($DIALOG --inputbox \
    "Please enter full path and name of file" \
    0 0); then
    cd $INSTALL_LOGS
    grep "$WHAT\$" * | view_file
  fi
}

set_email() {
  if ADMIN=$($DIALOG --ok-label "Commit" \
    --inputbox \
    "Please enter the email address of the person or role account that should receive reports from this box." \
    0 0 "$ADMIN"); then
    set_local_config "ADMIN" "$ADMIN"
  fi
}

set_delay() {
  if PROMPT_DELAY=$($DIALOG --ok-label "Commit" \
    --inputbox \
    "Please enter the time in seconds to wait for a response when prompted with a question." \
    0 0 "$PROMPT_DELAY"); then
    set_local_config "PROMPT_DELAY" "$PROMPT_DELAY"
  fi
}

queue_menu() {
  [ ! -d /var/log/lunar/queue ] || mkdir -p /var/log/lunar/queue
  while
    I_HELP="View the list of modules selected for installation"
    i_HELP="Edit the list of modules selected for installation"
    R_HELP="View the list of modules selected for removal"
    r_HELP="Edit the list of modules selected for removal"
    M_HELP="View the datafile of installed modules"
    m_HELP="Edit the datafile of installed modules"

    COMMAND=$($DIALOG --title "Queue Menu" \
      --ok-label "Select" \
      --cancel-label "Exit" \
      --default-item $COMMAND \
      --item-help \
      --menu \
      "" \
      0 40 6 \
      "I" "View     install   queue" "$I_HELP" \
      "i" "Edit     install   queue" "$i_HELP" \
      "R" "View     removal   queue" "$R_HELP" \
      "r" "Edit     removal   queue" "$r_HELP" \
      "M" "View     module    status" "$M_HELP" \
      "m" "Edit     module    status" "$m_HELP")
  do
    case $COMMAND in
      M) show_file $MODULE_STATUS ;;
      m)
        edit_file $MODULE_STATUS
        cp $MODULE_STATUS \
          $MODULE_STATUS_BACKUP
        ;;
      I) show_file $INSTALL_QUEUE ;;
      i) edit_file $INSTALL_QUEUE ;;
      R) show_file $REMOVE_QUEUE ;;
      r) edit_file $REMOVE_QUEUE ;;
    esac
  done
}

maintenance_menu() {
  while
    F_HELP="Check and fix all modules and internal state of lunar"
    N_HELP="Check all modules but do not fix the internal state"
    D_HELP="Check and fix the dependency database of lunar"
    P_HELP="Prune old sources and install/compile logs"
    A_HELP="Change selected or select new alias mappings"

    COMMAND=$($DIALOG --title "Maintenance Menu" \
      --ok-label "Select" \
      --cancel-label "Exit" \
      --default-item $COMMAND \
      --item-help \
      --menu \
      "" \
      0 40 6 \
      "F" "Fix everything" "$F_HELP" \
      "N" "Check everything but don't fix" "$N_HELP" \
      "D" "Fix dependencies" "$D_HELP" \
      "P" "Prune old sources and logs" "$P_HELP" \
      "A" "Select or Change Aliases" "$A_HELP")
  do
    case $COMMAND in
      F) lunar fix ;;
      N) lunar nofix ;;
      D) lunar fixdepends ;;
      P) lunar prune ;;
      A) select_aliases ;;
    esac
    if [ $COMMAND != "A" ]; then
      message "${MESSAGE_COLOR}Press enter to return...${DEFAULT_COLOR}"
      read
    fi
  done
}

log_menu() {
  while
    C_HELP="View compile logs of previously installed software"
    G_HELP="Discover a file's origin"
    I_HELP="View logs of files previously installed"
    c_HELP="Remove a compile log"
    i_HELP="Edit a log of files previously installed"

    COMMAND=$($DIALOG --title "Log Menu" \
      --ok-label "Select" \
      --cancel-label "Exit" \
      --default-item $COMMAND \
      --item-help \
      --menu \
      "" \
      0 40 5 \
      "G" "Grep    install logs" "$G_HELP" \
      "I" "View    install log" "$I_HELP" \
      "i" "Edit    install log" "$i_HELP" \
      "C" "View    compile log" "$C_HELP" \
      "c" "Remove  compile log" "$c_HELP")
  do
    case $COMMAND in
      G) grep_install_logs ;;
      I) show_file $(file_menu $INSTALL_LOGS) ;;
      i) edit_file $(file_menu $INSTALL_LOGS) ;;
      C) show_file $(file_menu $COMPILE_LOGS) ;;
      c) rm -f $(file_menu $COMPILE_LOGS) ;;
    esac
  done
}

feature_menu() {
  A_HELP="Create convenient auto-install scripts for common executables?"
  C_HELP="Colorized messages on lin and lrm?"
  E_HELP="Remove files when lrm?"
  F_HELP="Check for and repair broken programs after updating lunar?"
  G_HELP="Install the garbage documentation? (extras like README, LICENSE etc)"
  H_HELP="Automatically resurrect modules instead of compiling them?"
  I_HELP="Create archives of installed software?"
  K_HELP="Keep source code in /usr/src on good compiles? (gcc profiling needs it)"
  M_HELP="Email reports?"
  O_HELP="Preserve old libaries on module upgrade until lunar fix has completed?"
  P_HELP="Preserve modified files or backup them up and overwrite with defaults?"
  R_HELP="Prompt to view reports?"
  S_HELP="Play audio with prompts?"
  T_HELP="Disallow lrm of modules that would cause terrible malfunctions?"
  U_HELP="Automatically remove old sources and install caches upon lunar update?"
  V_HELP="View compilation as it happens? Deselect VOYEUR_progress"
  VP_HELP="Display progressbar during compilation? Deselect VOYEUR"
  W_HELP="Verbose display of compilation process?"
  X_HELP="When using --probe, also recompile modules if a newer version is available?"
  Z_HELP="Custom modules in zlocal override equally named ones (NOT RECOMMENDED) ?"
  L_HELP="Use xz compression for logs and caches?"
  MA_HELP="Log moonbase installations in the activity log?"
  FS_HELP="Check if there is enough available space on the disk before installing (REQUIRED_FREE_SPACE=$REQUIRED_FREE_SPACE)?"

  ARCHIVE=${ARCHIVE:-on}
  AUTORESURRECT=${AUTORESURRECT:-on}
  AUTOFIX=${AUTOFIX:-on}
  AUTOPRUNE=${AUTOPRUNE:-off}
  CHECK_FREE_SPACE=${CHECK_FREE_SPACE:-on}
  COLOR=${COLOR:-on}
  KEEP_SOURCE=${KEEP_SOURCE:-off}
  KEEP_OBSOLETE_LIBS=${KEEP_OBSOLETE_LIBS:-on}
  MAIL_REPORTS=${MAIL_REPORTS:-off}
  MOONBASE_ACT_LOG=${MOONBASE_ACT_LOG:-on}
  VIEW_REPORTS=${VIEW_REPORTS:-off}
  PRESERVE=${PRESERVE:-on}
  SOUND=${SOUND:-off}
  SUSTAIN=${SUSTAIN:-on}
  VOYEUR=${VOYEUR:-on}
  REAP=${REAP:-on}
  GARBAGE=${GARBAGE:-on}
  VERBOSE=${VERBOSE:-off}

  case $VOYEUR in
    off)
      VOYEUR=off
      VOYEUR_progress=off
      ;;
    p*)
      VOYEUR=off
      VOYEUR_progress=on
      ;;
    *)
      VOYEUR=on
      VOYEUR_progress=off
      ;;
  esac

  case $COMPRESS_METHOD in
    xz) COMPRESS_XZ=on ;;
    bz2) COMPRESS_XZ=off ;;
    *) COMPRESS_XZ=on ;;
  esac

  if TOGGLES=$($DIALOG --title "Feature Menu" \
    --no-cancel \
    --item-help \
    --separate-output \
    --checklist \
    "" \
    0 40 14 \
    "ARCHIVE" "Toggle" "$ARCHIVE" "$I_HELP" \
    "AUTORESURRECT" "Toggle" "$AUTORESURRECT" "$H_HELP" \
    "AUTOFIX" "Toggle" "$AUTOFIX" "$F_HELP" \
    "AUTOPRUNE" "Toggle" "$AUTOPRUNE" "$U_HELP" \
    "CHECK_FREE_SPACE" "Toggle" "$CHECK_FREE_SPACE" "$FS_HELP" \
    "COLOR" "Toggle" "$COLOR" "$C_HELP" \
    "KEEP_SOURCE" "Toggle" "$KEEP_SOURCE" "$K_HELP" \
    "KEEP_OBSOLETE_LIBS" "Toggle" "$KEEP_OBSOLETE_LIBS" "$O_HELP" \
    "GARBAGE" "Toggle" "$GARBAGE" "$G_HELP" \
    "MAIL_REPORTS" "Toggle" "$MAIL_REPORTS" "$M_HELP" \
    "MOONBASE_ACT_LOG" "Toogle" "$MOONBASE_ACT_LOG" "$MA_HELP" \
    "PRESERVE" "Toggle" "$PRESERVE" "$P_HELP" \
    "SOUND" "Toggle" "$SOUND" "$S_HELP" \
    "SUSTAIN" "Toggle" "$SUSTAIN" "$T_HELP" \
    "VIEW_REPORTS" "Toggle" "$VIEW_REPORTS" "$R_HELP" \
    "VOYEUR" "Choice" "$VOYEUR" "$V_HELP" \
    "VOYEUR_progress" "Choice" "$VOYEUR_progress" "$VP_HELP" \
    "REAP" "Toggle" "$REAP" "$E_HELP" \
    "VERBOSE" "Toggle" "$VERBOSE" "$W_HELP" \
    "ZLOCAL_OVERRIDES" "Toggle" "$ZLOCAL_OVERRIDES" "$Z_HELP" \
    "PROBE_EXPIRED" "Toggle" "$PROBE_EXPIRED" "$X_HELP" \
    "COMPRESS_XZ" "Toggle" "$COMPRESS_XZ" "$L_HELP"); then

    ARCHIVE=off
    AUTORESURRECT=off
    AUTOFIX=off
    AUTOPRUNE=off
    CHECK_FREE_SPACE=off
    COLOR=off
    KEEP_SOURCE=off
    KEEP_OBSOLETE_LIBS=off
    MAIL_REPORTS=off
    MOONBASE_ACT_LOG=off
    PRESERVE=off
    SOUND=off
    SUSTAIN=off
    VIEW_REPORTS=off
    VOYEUR=off
    REAP=off
    GARBAGE=off
    VERBOSE=off
    ZLOCAL_OVERRIDES=off
    PROBE_EXPIRED=off
    COMPRESS_METHOD=xz

    for TOGGLE in $TOGGLES; do
      case $TOGGLE in
        ARCHIVE) ARCHIVE=on ;;
        AUTORESURRECT) AUTORESURRECT=on ;;
        AUTOFIX) AUTOFIX=on ;;
        AUTOPRUNE) AUTOPRUNE=on ;;
        CHECK_FREE_SPACE) CHECK_FREE_SPACE=on ;;
        COLOR) COLOR=on ;;
        KEEP_SOURCE) KEEP_SOURCE=on ;;
        KEEP_OBSOLETE_LIBS) KEEP_OBSOLETE_LIBS=on ;;
        MAIL_REPORTS) MAIL_REPORTS=on ;;
        MOONBASE_ACT_LOG) MOONBASE_ACT_LOG=on ;;
        PRESERVE) PRESERVE=on ;;
        SOUND) SOUND=on ;;
        SUSTAIN) SUSTAIN=on ;;
        VIEW_REPORTS) VIEW_REPORTS=on ;;
        VOYEUR) VOYEUR=on ;;
        VOYEUR_progress) if [ $VOYEUR_progress == off ]; then
          VOYEUR=progress
        else
          VOYEUR=${VOYEUR/off/progress}
        fi ;;
        REAP) REAP=on ;;
        GARBAGE) GARBAGE=on ;;
        VERBOSE) VERBOSE=on ;;
        ZLOCAL_OVERRIDES) ZLOCAL_OVERRIDES=on ;;
        PROBE_EXPIRED) PROBE_EXPIRED=on ;;
        COMPRESS_XZ)
          COMPRESS_METHOD=xz
          COMPRESS_METHOD_ARGS="-T 0"
          ;;
      esac
    done

    set_local_config "ARCHIVE" "$ARCHIVE"
    set_local_config "AUTORESURRECT" "$AUTORESURRECT"
    set_local_config "AUTOFIX" "$AUTOFIX"
    set_local_config "AUTOPRUNE" "$AUTOPRUNE"
    set_local_config "CHECK_FREE_SPACE" "$CHECK_FREE_SPACE"
    set_local_config "KEEP_SOURCE" "$KEEP_SOURCE"
    set_local_config "KEEP_OBSOLETE_LIBS" "$KEEP_OBSOLETE_LIBS"
    set_local_config "MAIL_REPORTS" "$MAIL_REPORTS"
    set_local_config "MOONBASE_ACT_LOG" "$MOONBASE_ACT_LOG"
    set_local_config "PRESERVE" "$PRESERVE"
    set_local_config "SOUND" "$SOUND"
    set_local_config "SUSTAIN" "$SUSTAIN"
    set_local_config "VIEW_REPORTS" "$VIEW_REPORTS"
    set_local_config "VOYEUR" "$VOYEUR"
    set_local_config "REAP" "$REAP"
    set_local_config "GARBAGE" "$GARBAGE"
    set_local_config "VERBOSE" "$VERBOSE"
    set_local_config "ZLOCAL_OVERRIDES" "$ZLOCAL_OVERRIDES"
    set_local_config "PROBE_EXPIRED" "$PROBE_EXPIRED"
    set_local_config "COLOR" "$COLOR"
    set_local_config "COMPRESS_METHOD" "$COMPRESS_METHOD"
    if [ "$COMPRESS_METHOD" = "xz" ]; then
      set_local_config "COMPRESS_METHOD_ARGS" "$COMPRESS_METHOD_ARGS"
    else
      unset_local_config "COMPRESS_METHOD_ARGS"
    fi
  fi
}

option_menu() {
  while
    P_HELP="Enter the default delay time for prompts"
    E_HELP="Enter the email address for this box's administrator"
    F_HELP="Select many options on or off at once"
    M_HELP="Select ftp and http mirrors for faster downloads"
    O_HELP="Select architecture optimizations"
    I_HELP="Select the test that lunar fix, and AUTOFIX execute"
    D_HELP="Options for downloads"
    A_HELP="Select accepted licenses"
    R_HELP="Select rejected licenses"

    COMMAND=$($DIALOG --title "Option Menu" \
      --item-help \
      --ok-label "Select" \
      --cancel-label "Exit" \
      --menu \
      "" \
      0 40 8 \
      "P" "Prompt Delay" "$P_HELP" \
      "D" "Download Options" "$D_HELP" \
      "E" "Admin's Email" "$E_HELP" \
      "F" "Feature Menu" "$F_HELP" \
      "I" "Integrity Checking" "$I_HELP" \
      "M" "Software Mirrors" "$M_HELP" \
      "O" "Optimize Architecture" "$O_HELP" \
      "A" "Accepted licenses" "$A_HELP" \
      "R" "Rejected licenses" "$R_HELP")
  do

    case $COMMAND in
      P) set_delay ;;
      D) download_options ;;
      E) set_email ;;
      F) feature_menu ;;
      I) integrity_menu ;;
      M) mirror_menu ;;
      O) optimize_menu ;;
      A) set_accepted_licenses ;;
      R) set_rejected_licenses ;;
    esac
  done
}

goodbye() {
  echo "Have a good day."
  exit
}

background_execute() {
  $DIALOG --msgbox "Processing queues in the background." 0 0

  [ -f $REMOVE_QUEUE ] &&
    lrm $(cat "$REMOVE_QUEUE") 1>/dev/null 2>&1
  rm -f $REMOVE_QUEUE

  if [ -f $INSTALL_QUEUE ]; then
    lin --deps $(cat "$INSTALL_QUEUE")
    (
      lin $(cat "$INSTALL_QUEUE") 1>/dev/null 2>&1 &&
        rm -f $INSTALL_QUEUE
    ) &
  fi

  goodbye
}

foreground_execute() {
  [ -f $REMOVE_QUEUE ] && lrm $(cat "$REMOVE_QUEUE")
  rm -f $REMOVE_QUEUE

  [ -f $INSTALL_QUEUE ] && lin $(cat "$INSTALL_QUEUE")
  rm -f $INSTALL_QUEUE

  goodbye
}

setvar() {
  if [ -z "$*" ]; then
    sort -n "$LOCAL_CONFIG" | grep -v -e UNIQID -e color | while read LINE; do
      printf "%32s %s\n" "$(echo $LINE | cut -d= -f1)" "$(echo $LINE | cut -d= -f2-)"
    done
  else
    VAR=$1
    shift
    if [ -z "$*" ]; then
      VAL=$(get_local_config "$VAR")
      printf "%s=%s\n" "$VAR" "$VAL"
    else
      set_local_config "$VAR" "$@"
    fi
  fi
}

unsetvar() {
  if [ ! -z "$*" ]; then
    unset_local_config "$1"
  fi
}

main_menu() {
  while
    M_HELP="Easy module management"
    O_HELP="Change lunar options and features"
    L_HELP="View and edit lunar generated log files."
    Q_HELP="View and edit lunar queues."
    F_HELP="Process queues while you watch and wait"
    N_HELP="Discover and fix internal problems"
    B_HELP="Process queues in the background"
    E_HELP="Exit without processing queues"
    OK="Select"
    CANCEL="Exit"

    COMMAND=$($DIALOG --title "Main Menu" \
      --item-help \
      --ok-label "$OK" \
      --cancel-label "$CANCEL" \
      --menu \
      "$LUNAR_MODULE version: $LUNAR_VERSION" \
      0 0 0 \
      "M" "Module      Menu" "$M_HELP" \
      "O" "Option      Menu" "$O_HELP" \
      "L" "Log         Menu" "$L_HELP" \
      "Q" "Queue       Menu" "$Q_HELP" \
      "N" "Maintenance Menu" "$N_HELP" \
      "F" "Foreground  Execute" "$F_HELP" \
      "B" "Background  Execute" "$B_HELP")
  do
    case $COMMAND in
      M) module_menu ;;
      O) option_menu ;;
      L) log_menu ;;
      Q) queue_menu ;;
      N) maintenance_menu ;;
      F) foreground_execute ;;
      B) background_execute ;;
    esac
  done
}

DIALOG="dialog
--backtitle
Lunar Module Management Utility
--stdout"

main() {
  #lets load the menu code
  if [ -n "$MENUS" ]; then
    for FILE in $(echo $MENUS/*.menu); do
      [ -s "$FILE" ] && . "$FILE"
    done
  fi

  export IFS="$TAB_ENTER_IFS"

  LUNAR_MODULE=${LUNAR_MODULE:-lunar}
  LUNAR_VERSION=$(run_details $LUNAR_MODULE && echo $UPDATED)

  main_menu
}

. /etc/lunar/config
. $BOOTSTRAP

GETOPT_ARGS=$(getopt -q -n lunar -o "dhv" -l "debug,help,verbose" -- "$@")

if [ -z "$?" ]; then
  help | view_file
  exit
else
  eval set -- $GETOPT_ARGS
  root_check
  enviro_check
  set_priority

  while true; do
    case "$1" in
      -d | --debug)
        ((LUNAR_DEBUG++))
        export LUNAR_DEBUG
        shift
        ;;
      -h | --help)
        help
        exit 1
        ;;
      -v | --verbose)
        export VERBOSE="on"
        shift
        ;;
      --)
        shift
        break
        ;;
      *)
        help
        break
        ;;
    esac
  done

  case "$1" in
    prune) prune ;;
    renew) renew ;;
    update) update ;;
    rebuild) rebuild ;;
    optimize) optimize_menu ;;
    set) shift && setvar $@ ;;
    unset) shift && unsetvar $@ ;;
    fix) shift && run_fix $@ ;;
    nofix) shift && export NOFIX=on && run_fix $@ ;;
    fixdepends) shift && fix_depends $@ ;;
    resurrect) shift && resurrect_modules $@ ;;
    install) shift && lin $@ ;;
    remove) shift && lrm $@ ;;
    hold) shift && hold_modules $@ ;;
    unhold) shift && unhold_modules $@ ;;
    exile) shift && exile_modules $@ ;;
    unexile) shift && unexile_modules $@ ;;
    enforce) shift && enforce_modules $@ ;;
    unenforce) shift && unenforce_modules $@ ;;
    *) main ;;
  esac
fi
