#!/bin/bash
#########################################################
#                                                       #
# This is BashStyle-NG                                  #
#                                                       #
# Licensed under GNU GENERAL PUBLIC LICENSE v3          #
#                                                       #
# Copyright Christopher Roy Bratušek                    #
#                                                       #
#########################################################

. gettext.sh
export TEXTDOMAIN="bashstyle-rc"

# environment variables
export BSNG_PREFIX=/usr
export BSNG_DATADIR=/usr/share
export BSNG_RCDIR=${BSNG_DATADIR}/bashstyle-ng/rc
export BSNG_VERSION=11.1
export BSNG_YEAR="2007 - 2026"
export BSNG_BASHVER=${BASH_VERSINFO[0]}${BASH_VERSINFO[1]}
export BSNG_LOGFILE=${HOME}/.bashstyle-ng.log
export BASH_SESSION_PID=$$

BSNG_SESSION_TIME=$(date +%I-%M-%S-%N)
export BSNG_SESSION_TIME

# load ini / loggin functions
source ${BSNG_RCDIR}/function_ini
source ${BSNG_RCDIR}/function_log

# global aliases / settings
alias bt="check bt"
alias bf="check bf"

dbg_log shopt -s checkwinsize

# start logging
verbose=$(ini_get debug_verbose)
if [[ ${verbose} == True ]]; then
    dbg_log "$(eval_gettext "BashStyle-NG Starting")"
else
    echo "$(eval_gettext "BashStyle-NG Starting")"
fi
dbg_msg "$(eval_gettext "BashStyle-NG Bash Major Version:")" "${BASH_VERSINFO[0]}"
dbg_msg "$(eval_gettext "BashStyle-NG Bash Minor Version:")" "${BASH_VERSINFO[1]}"
dbg_msg "$(eval_gettext "BashStyle-NG Bash Patch Level:")" "${BASH_VERSINFO[2]}"
dbg_msg "$(eval_gettext "BashStyle-NG Version:")" "${BSNG_VERSION}"
dbg_msg "$(eval_gettext "BashStyle-NG Prefix:")" "${BSNG_PREFIX}"
dbg_msg "$(eval_gettext "BashStyle-NG Logfile:")" "${BSNG_LOGFILE}"

# check whether ini is up-to-date
bashstyle-config-helper --update >/dev/null

# do trapping stuff
# by Richard Hansen https://stackoverflow.com/a/7287873

trap_log () { printf '%s\n' "$*"; }
trap_error () { trap_log "$(eval_gettext "ERROR:")" "$*" >&2; }
trap_fatal () { trap_error "$@"; exit 1; }

bashstyle_trap_add () {
    trap_add_cmd=$1; shift || trap_fatal "${FUNCNAME[0]}" "$(eval_gettext "invalid syntax")"
    for trap_add_name in "$@"; do
    trap -- "$(
        extract_trap_cmd() { printf '%s\n' "$3"; }
        eval "extract_trap_cmd $(trap -p "${trap_add_name}")"
        printf '%s\n' "${trap_add_cmd}"
    )" "${trap_add_name}" \
        || trap_fatal "$(eval_gettext "unable to add ${trap_add_cmd} to trap ${trap_add_name}")"

    unset trap_add_cmd trap_add_name
    done
}

declare -f -t bashstyle_trap_add

bashstyle_cleanup () {
    rm -f "${HOME}/.*.bs-ng.${BSNG_SESSION_TIME}_${BASH_SESSION_PID}"
}

bashstyle_trap_add 'bashstyle_cleanup' EXIT

# setup PATH
if [ -n "$(ini_get path)" ]; then
    dbg_msg "$(eval_gettext "BashStyle-NG Setting:")" PATH "${PATH}"
    PATH="$(ini_get path)"
fi

bt "$(ini_get path_wd)" && export PATH="${PATH}:."
[[ ${PATH} != *games* && -d /usr/games/ ]] && export PATH="${PATH}:/usr/games:/usr/local/games"
[[ ${PATH} != *${HOME}/bin* && -d ${HOME}/bin ]] && export PATH="${PATH}:${HOME}/bin"

# color settings: general, ls and manpages
if bt "$(ini_get enable_colors)"; then
    dbg_log source ${BSNG_RCDIR}/settings_color
    bt "$(ini_get use_lscolors)" && dbg_log source ${BSNG_RCDIR}/settings_ls
    bt "$(ini_get less_termcap_color)" && dbg_log source ${BSNG_RCDIR}/settings_man
fi

# Bash prompt theming
if bt "$(ini_get use_bashstyle)"; then
    dbg_msg "$(eval_gettext "BashStyle-NG Loading:")" BashStyle-NG
    dbg_log source ${BSNG_RCDIR}/styles_hook

    # load custom settings file
    if [[ -f ${HOME}/.bashstyle.custom ]]; then
        dbg_msg "$(eval_gettext "BashStyle-NG Loading:")" "$(eval_gettext "Custom Settings")"
        dbg_log source "${HOME}/.bashstyle.custom"
    fi

    if [[ ${BSNG_BASHVER} -ge 44 && -n $(ini_get ps0) ]]; then
        dbg_msg "$(eval_gettext "BashStyle-NG Setting:")" PS0 "$(ini_get ps0)"
        PS0="${color_ps0} $(ini_get ps0)${color_font} "
    fi

    dbg_msg "$(eval_gettext "BashStyle-NG Setting:")" PS2 "$(ini_get ps2)"
    PS2="${color_ps2} $(ini_get ps2)${color_font} "

    dbg_msg "$(eval_gettext "BashStyle-NG Setting:")" PS3 "$(ini_get ps3)"
    PS3="${color_ps3} $(ini_get ps3)${color_font} "

    dbg_msg "$(eval_gettext "BashStyle-NG Setting:")" PS4 "$(ini_get ps4)"
    PS4="${color_ps4} $(ini_get ps4)${color_font} "

    if bt "$(ini_get random_style)"; then
        dbg_msg "$(eval_gettext "BashStyle-NG Setting:")" "$(eval_gettext "Random Prompt")"

        number=$(random -r 11)
        case ${number} in
            0 ) pstyle=separator ;;
            1 ) pstyle=vector ;;
            2 ) pstyle=clock ;;
            3 ) pstyle=equinox ;;
            4 ) pstyle=elite ;;
            5 ) pstyle=poweruser ;;
            6 ) pstyle=dirks ;;
            7 ) pstyle=dot_prompt ;;
            8 ) pstyle=sepa_ng ;;
            9 ) pstyle=quirk ;;
            10 ) pstyle=sputnik ;;
            11 ) pstyle=ayoli ;;
        esac

        dbg_msg "$(eval_gettext "BashStyle-NG Setting:")" "${pstyle}" "$(eval_gettext "randomly chosen")"
    else
        pstyle=$(ini_get prompt_style)
    fi

    if bt "$(ini_get use_custom_prompt)"; then
        dbg_msg "$(eval_gettext "BashStyle-NG Setting:")" "$(eval_gettext "Custom")" Prompt
        dbg_log source ${BSNG_RCDIR}/styles_custom
    elif [[ -e ${BSNG_RCDIR}/styles_${pstyle} ]]; then
        dbg_msg "$(eval_gettext "BashStyle-NG Setting:")" "${pstyle}" Prompt
        dbg_log source "${BSNG_RCDIR}/styles_${pstyle}"
    elif [[ "${pstyle}" == "None" ]]; then
        dbg_msg "$(eval_gettext "BashStyle-NG Setting:")" "$(eval_gettext "No")" Prompt "$(eval_gettext "[to keep System default or use another tool for setting Prompt]")"
    else
        dbg_msg "$(eval_gettext "BashStyle-NG Setting:")" "$(eval_gettext "Fallback")" Prompt
        dbg_log export PS1="\u@\h\w: "
    fi
fi

# readline settings
bt "$(ini_get use_readlinecfg)" && dbg_log source ${BSNG_RCDIR}/settings_readline
bt "$(ini_get use_keybindingscfg)" && dbg_log source ${BSNG_RCDIR}/settings_keybindings

# Bash settings: shopts and aliases
dbg_log source ${BSNG_RCDIR}/settings_shopt
dbg_log source ${BSNG_RCDIR}/settings_alias

# BashStyle settings: advanced
dbg_log source ${BSNG_RCDIR}/settings_options

# external settings: Vim, Nano and Git
bt "$(ini_get use_vimcfg)" && dbg_log source ${BSNG_RCDIR}/settings_vim
bt "$(ini_get use_nanocfg)" && dbg_log source ${BSNG_RCDIR}/settings_nano
bt "$(ini_get use_gitcfg)" && dbg_log source ${BSNG_RCDIR}/settings_git

# extra BashStyle functions
for module in cd remember_command colorshell history; do
    source ${BSNG_RCDIR}/function_${module}
done

# function to properly reload Bash
#xk2c from commandlinefu.com

reload_bash () {
    builtin unalias -a
    builtin unset -f "$(builtin compgen -A function)"
    for trap in EXIT DEBUG ERR; do
        trap '' "${trap}"
    done
    [ -f /etc/bash_completion ] && source /etc/bash_completion
    source "${HOME}"/.bashrc
}

# birthday greeting / welcome message
if [[ $(ini_get user_birthday) == $(date +%m-%d) ]]; then
    cat ${BSNG_RCDIR}/internal_birthday
elif [[ -n $(ini_get welcome_message) ]]; then
    welcome="$(ini_get welcome_message)"
    dbg_msg "$(eval_gettext "BashStyle-NG Setting:")" "$(eval_gettext "Welcome Message")"
    if check P "${welcome%\ *}"; then
        dbg_log eval "${welcome}"
    else
        dbg_log echo "${welcome}"
    fi
fi

# remember command / last exit status

dbg_msg "$(eval_gettext "Add remember command to DEBUG and ERR trap")"
bashstyle_trap_add 'bashstyle_remember_command' DEBUG
bashstyle_trap_add 'bashstyle_remember_command' ERR

# colorshell

if bt "$(ini_get colorshell)" && bt "$(ini_get enable_colors)"; then
    dbg_msg "$(eval_gettext "Add colorshell to DEBUG trap")"
    bashstyle_trap_add 'bashstyle_colorshell' DEBUG

    if bt "$(ini_get colorshell_reset)"; then
        dbg_msg "$(eval_gettext "Add colorshell-reset to DEBUG trap")"
        bashstyle_trap_add 'bashstyle_colorshell_reset' DEBUG
    fi
fi

# history syncronization

if bf "$(ini_get history_isolate)"; then
    alias history=bashstyle_history
    if bt "$(ini_get history_sync)"; then
        dbg_msg "$(eval_gettext "Add history syncronization to DEBUG trap")"
        bashstyle_trap_add 'bashstyle_history_sync' DEBUG
    fi
fi

# remember directory
if bt "$(ini_get restore_directory)"; then
bashstyle_remember_directory () {
    printf %s "${PWD}" > "${HOME}/.lastpwd"
}

    bashstyle_trap_add 'bashstyle_remember_directory' EXIT
fi

# clean-up

dbg_finalize

unset pstyle TEXTDOMAIN verbose colors style welcome
unset USER_DEFAULTS FACTORY_DEFAULTS VENDOR_DEFAULTS

unset -f bashstyle_trap_add
unset -f trap_fatal trap_error trap_log
unset -f ini_get ini_set ini_add def_get ven_get rc_add
unset -f dbg_msg dbg_log dbg_finalize

unalias bt
unalias bf

export BSNG_TRAP_RECORD=True
