# ======================================================================
#
# Database detector functions
# used in localdump.se and detector.sh
#
# it analyzes all ini files with database profiles and sets
# variables / environment to perform database backup/ restore
#
# Remark:
# The script that sources this file must source vendor/ini.class.sh
# before using these functions.
#
# ----------------------------------------------------------------------
# ======================================================================

# ----------------------------------------------------------------------
# CONFIG
# ----------------------------------------------------------------------

DBD_BASEDIR=plugins/localdump/profiles
declare -A DBD_PARAMS


# ----------------------------------------------------------------------
# FUNCTIONS
# ----------------------------------------------------------------------

# write debug output if DBD_DEBUG is enabled
# param  string  text to show
function dbdetect._wd(){
    test "$DBD_DEBUG" -ne "0" && color.echo "darkgray" "DEBUG: $*" >&2
}

# get a list of all config files
# param  string  full path of ini file
function dbdetect.getConfigs(){
    find ${DBD_BASEDIR} -type f -name "*.ini" | sort
}

# get type from given ini file
# param  string  full path of ini file
function dbdetect.getType(){
    basename "$1" | cut -d "_" -f 1 | sed "s,\.ini$,,"
}

# get profile from given ini file
# param  string  full path of ini file
function dbdetect.getProfile(){
    basename "$1" | cut -d "_" -f 1- | sed "s,\.ini$,,"
}

# check if the requirements for a database match
# param  string  full path of ini file to check
function dbdetect.exists(){
    local _config="$1"

    DBD_PARAMS=

    local _found=0

    # set file and inisection we read values from
    ini.set "$_config" "detect"
    
    # --- check tcp
    local tcpport; tcpport=$( ini.value "tcp" )
    if [ -n "$tcpport" ]; then
      local tcptarget; tcptarget=$( ini.value "tcp-target" )
      tcptarget=${tcptarget:-localhost}
      if { ! >/dev/tcp/$tcptarget/$tcpport; } > /dev/null 2>&1; then
          # echo "No port tcp $tcpport available"
          dbdetect._wd "... No port tcp $tcpport available on $tcptarget"
          return 1
      fi
      dbdetect._wd "... Found tcp $tcpport on $tcptarget."
    fi

    # --- check tcp process
    local tcpprocess; tcpprocess=$( ini.value "tcp-process" )
    if [ -n "$tcpprocess" ]; then
        if ! netstat -tulpen 2>/dev/null | grep "^tcp.*:${tcpport} .*/${tcpprocess}" >/dev/null; then
            # echo "No port tcp $tcpport available"
            dbdetect._wd "... $tcpprocess not found for tcp ${tcpport}"
            return 1
        fi
        dbdetect._wd "... tcp $tcpport is used by $tcpprocess."
    fi

    # --- check binaries
    local binary; binary=$( ini.value "binary" )
    if [ -n "${binary}" ]; then
        for mybinary in $( echo "${binary}" | tr "," " " ); do
            if ! j_requireBinary "$mybinary" 1 >/dev/null 2>&1; then
                dbdetect._wd "... Missing binary: ${mybinary}"
                return 1
            fi
            dbdetect._wd "... Binary: ${mybinary} was found"
        done
    fi

    # --- check process
    local process; process=$( ini.value "process" )
    if [ -n "${process}" ]; then
        if ! j_requireProcess "${process}" 1 >/dev/null; then
            dbdetect._wd "... Missing process: ${process}"
            return 1
        fi
        # if ! ps -eo command | grep -E "${process}" >/dev/null 2>&1; then
        #     dbdetect._wd "... Process ${process} was not found"
        #     return 1
        # fi
        dbdetect._wd "... Process ${process} was found"
    fi

    # --- check db files
    local filetype; filetype=$( ini.value "type" )

    if [ -n "${filetype}" ]; then
      local myfiles; declare -a myfiles
      for myfile in $( ini.value "file[]" )
      do
        if ! file -b "${myfile}" | grep -i "$filetype" >/dev/null; then
          dbdetect._wd "... File ${myfile} is not of type $filetype"
          return 1
        fi
        dbdetect._wd "... File ${myfile} is type $filetype"
        myfiles+="${myfile}|"
      done
      if [ -z "${myfiles}" ]; then
        dbdetect._wd "... No files for type [${filetype}] were added"
        return 1
      fi
    fi

    # --- OK, everything was found ... we initialize it
    dbdetect._wd "OK, match: $_config"

    ini.set "$_config" "set"
    local value
    local dbuser=$( ini.value "dbuser" )
    local dbpassword=$( ini.value "dbpassword" )


    for mykey in su env params
    do
        value="$( ini.value "$mykey" )"
        value="${value//\{\{tcp-port\}\}/$tcpport}"
        value="${value//\{\{tcp-target\}\}/$tcptarget}"
        value="${value//\{\{dbuser\}\}/$dbuser}"
        value="${value//\{\{dbpassword\}\}/$dbpassword}"
        value="${value//\{\{file\[\]\}\}/$myfiles}"
        
        DBD_PARAMS[$mykey]="$value"
        dbdetect._wd ">>> $mykey = $value"
    done
    dbdetect._wd ">>> files = $myfiles"
    DBD_PARAMS[files]="$myfiles"

    return 0
}

# set a profile name
function dbdetect.setProfile(){
  dbdetect.exists "${DBD_BASEDIR}/${PROFILENAME}.ini"
}

function dbdetect.getParams(){
    echo "${DBD_PARAMS['params']}"
}


# for backup scripts: get checked files from [detect] -> file[]
# 
function dbdetect.getFiles(){
    echo "${DBD_PARAMS['files']}" | tr "|" "\n"
}

# set variables in [set] -> env = ...
# USAGE:
# eval $( dbdetect.setenv )
function dbdetect.setenv(){
    echo "${DBD_PARAMS['env']}"
}

# unset variables from [set] -> env = ...
# USAGE:
# eval $( dbdetect.unsetenv )
function dbdetect.unssetenv(){
    echo "${DBD_PARAMS['env']}" | grep -o '[a-z0-9]*=' | tr -d '=' | sed "s,^,unset ,"
}

function dbdetect.runas(){
    echo "${DBD_PARAMS['su']}"
}

# ----------------------------------------------------------------------
