# This file is generated by https://github.com/adoyle-h/lobash
# Command: lobash-gen -c ./lobash.conf
# Author: ADoyle <adoyle.h@gmail.com>
# License: Apache License Version 2.0
# Version: 0.4.0
# Prefix: l.
# Bash Minimum Version: 4.4
# Included Modules: parse_params start_with match match_list

######################## Lobash Internals ########################

_lobash.0_4_0_105561700_18605_detect_os() {
  local kernel_name
  kernel_name="$(uname -s)"

  case "$kernel_name" in
    "Darwin")                         echo MacOS ;;
    "SunOS")                          echo Solaris ;;
    "Haiku")                          echo Haiku ;;
    "MINIX")                          echo MINIX ;;
    "AIX")                            echo AIX ;;
    "IRIX"*)                          echo IRIX ;;
    "FreeMiNT")                       echo FreeMiNT ;;
    "Linux" | "GNU"*)                 echo Linux ;;
    *"BSD" | "DragonFly" | "Bitrig")  echo BSD ;;
    "CYGWIN"* | "MSYS"* | "MINGW"*)   echo Windows ;;
    *)                                echo Unknown_OS "$kernel_name" ;;
  esac
}



[[ -n ${_LOBASH_0_4_0_105561700_18605_INTERNAL_FUNC_PREFIX:-} ]] && return

readonly _LOBASH_0_4_0_105561700_18605_INTERNAL_FUNC_PREFIX=_lobash.
readonly _LOBASH_0_4_0_105561700_18605_INTERNAL_CONST_PREFIX=_LOBASH_
readonly _LOBASH_0_4_0_105561700_18605_PRIVATE_FUNC_PREFIX=_l.
readonly _LOBASH_0_4_0_105561700_18605_PRIVATE_CONST_PREFIX=_L_
readonly _LOBASH_0_4_0_105561700_18605_PUBLIC_FUNC_PREFIX=l.
readonly _LOBASH_0_4_0_105561700_18605_PUBLIC_CONST_PREFIX=L_

readonly _LOBASH_0_4_0_105561700_18605_PREFIX=l.
readonly _LOBASH_0_4_0_105561700_18605_PUBLIC_DEPTH=2
readonly _LOBASH_0_4_0_105561700_18605_MIN_BASHVER=4.4

readonly _LOBASH_0_4_0_105561700_18605_OS=$(_lobash.0_4_0_105561700_18605_detect_os)

_lobash.0_4_0_105561700_18605_is_bash() {
  [[ -n "${BASH_VERSION:-}" ]]
}

_lobash.0_4_0_105561700_18605_check_os() {
  if [[ ! $_LOBASH_0_4_0_105561700_18605_OS =~ ^(Linux|MacOS|BSD)$ ]]; then
    echo "Not support current system: $_LOBASH_0_4_0_105561700_18605_OS" >&2
    return 5
  fi
}

_lobash.0_4_0_105561700_18605_check_shell() {
  if ! _lobash.0_4_0_105561700_18605_is_bash; then
    echo 'Lobash only work in Bash.' >&2
    return 6
  fi
}

_lobash.0_4_0_105561700_18605_check_supported_bash_version() {
  local info
  read -r -d '.' -a info <<< "$_LOBASH_0_4_0_105561700_18605_MIN_BASHVER"
  if (( BASH_VERSINFO[0] < info[0] )) \
    || ( (( BASH_VERSINFO[0] == info[0] )) && (( BASH_VERSINFO[1] < info[1] )) ); then
    echo "Bash $BASH_VERSION is not supported. Upgrade your Bash to $_LOBASH_0_4_0_105561700_18605_MIN_BASHVER or higher version." >&2
    return 7
  fi
}

_lobash.0_4_0_105561700_18605_check_support() {
  _lobash.0_4_0_105561700_18605_check_os
  _lobash.0_4_0_105561700_18605_check_shell
  # _lobash.0_4_0_105561700_18605_check_supported_bash_version
}

_lobash.0_4_0_105561700_18605_check_support

_lobash.0_4_0_105561700_18605_dirname() {
  local str=${1:-}
  [[ $str == '/' ]] && echo '/' && return 0
  [[ $str =~ ^'../' ]] && echo '.' && return 0
  [[ ! $str =~ / ]] && echo '.' && return 0

  printf '%s\n' "${str%/*}"
}

_lobash.0_4_0_105561700_18605_with_IFS() {
  local IFS=$1
  shift
  eval "$@"
}

######################## Private Methods ########################


_l.0_4_0_105561700_18605_parse_single_hyphen_options() {
  local param=${1#-}

  # Possible Formats:
  # -a 3 or -abc 3
  # -a or -a3 or -abc3
  # -a=3 or -abc=3
  # -a= or -abc=

  local -a matches=()
  local k letters
  l.0_4_0_105561700_18605_match_list "$param" '^(.+)=(.*)$' matches
  if (( ${#matches[@]} == 2 )); then
    # -a=3 or -abc=3
    # -a= or -abc=
    letters=${matches[0]}
    $add_opt "${letters: -1:1}" "${matches[1]}"

    letters=${letters:0:$(( ${#letters} - 1 ))}
    for (( k = 0; k < ${#letters} ; k++ )); do
      $add_opt "${letters:$k:1}" true
    done
    return
  fi

  if (( $# == 2 )); then
    # -a 3 or -abc 3
    $add_opt "${param: -1:1}" "$2"
    (( i+=1 ))

    letters=${param:0:$(( ${#param} - 1 ))}
    for (( k = 0; k < ${#letters}; k++ )); do
      $add_opt "${letters:$k:1}" true
    done
    return
  else
    # -a or -a3 or -abc3
    for (( k = 0; k < ${#param}; k++ )); do
      $add_opt "${param:$k:1}" true
    done
    return
  fi

  echo "Unknown option: -$param" >&2
  return 4
}

_l.0_4_0_105561700_18605_parse_double_hyphen_options() {
  local param=${1#--}

  local -a matches=()
  l.0_4_0_105561700_18605_match_list "$param" '^(.+)=(.*)' matches

  if (( ${#matches[@]} == 2 )); then
    $add_opt "${matches[0]}" "${matches[1]}"
  else
    local key
    key=$(l.0_4_0_105561700_18605_match "$param" '^no-(.+)')
    if [[ -n $key ]]; then
      $add_opt "${key}" false
    else
      key=$param
      if (( $# == 2 )); then
        $add_opt "${key}" "$2"
      else
        $add_opt "${key}" true
      fi
    fi
  fi
}

_l.0_4_0_105561700_18605_parse_params_add_none() {
  return 0
}

_l.0_4_0_105561700_18605_parse_params_add_opt() {
  eval "$opts_name[\$1]=\"\$2\""
}

_l.0_4_0_105561700_18605_parse_params_add_arg() {
  eval "$args_name+=(\"\$1\")"
}

l.0_4_0_105561700_18605_parse_params() {
  if (( $# < 2 )); then
    echo "parse_params: programming error. Parameters cannot less than 2." >&2
    return 3
  fi

  local add_opt add_arg
  if [[ $1 != _ ]]; then
    local opts_name=$1
    add_opt=_l.0_4_0_105561700_18605_parse_params_add_opt
  else
    add_opt=_l.0_4_0_105561700_18605_parse_params_add_none
  fi

  if [[ $2 != _ ]]; then
    local args_name=$2
    add_arg=_l.0_4_0_105561700_18605_parse_params_add_arg
  else
    add_arg=_l.0_4_0_105561700_18605_parse_params_add_none
  fi

  local param_size=$#
  local param
  local rest_is_args=false
  for (( i = 3; i <= param_size; i++ )); do
    param=${!i}

    if l.0_4_0_105561700_18605_start_with "$param" '-'; then
      local j=$(( i+1 ))
      local f

      if [[ $param == '--' ]]; then
        rest_is_args=true
        (( i+=1 ))
        break;
      fi

      if l.0_4_0_105561700_18605_start_with "$param" '--'; then
        f=_l.0_4_0_105561700_18605_parse_double_hyphen_options
      else
        f=_l.0_4_0_105561700_18605_parse_single_hyphen_options
      fi

      if (( j > param_size )) ; then
        $f "$param"
      else
        local next=${!j}
        if l.0_4_0_105561700_18605_start_with "$next" '-' ; then
          $f "$param"
        else
          $f "$param" "$next"
        fi
      fi
    else
      $add_arg "$param"
    fi
  done

  if [[ $rest_is_args == true ]]; then
    for (( ; i <= param_size; i++ )); do
      $add_arg "${!i}"
    done
  fi
}


l.0_4_0_105561700_18605_start_with() {
  [[ $2${1##"$2"} == "$1" ]]
}


l.0_4_0_105561700_18605_match() {
  [[ ${3:-} == 0 ]] && echo "index cannot be 0" >&2 && return 3

  if [[ $1 =~ $2 ]]; then
    if (( ${#BASH_REMATCH[@]} > 1 )); then
      printf '%s\n' "${BASH_REMATCH[${3:-1}]}"
    else
      echo ''
    fi
  else
    echo ''
  fi
}


l.0_4_0_105561700_18605_match_list() {
  (( $# != 3 )) && echo "wrong parameters" >&2 && return 3

  local output_array_name=$3

  if [[ $1 =~ $2 ]]; then
    local len=${#BASH_REMATCH[@]}
    local i
    if (( len > 1 )); then
      for (( i = 1; i < len; i++ )); do
        eval "${output_array_name}+=( \"\${BASH_REMATCH[$i]}\" )"
      done
    fi
  fi
}

######################## Public Methods ########################
l.parse_params() { l.0_4_0_105561700_18605_parse_params "$@"; }
l.start_with() { l.0_4_0_105561700_18605_start_with "$@"; }
l.match() { l.0_4_0_105561700_18605_match "$@"; }
l.match_list() { l.0_4_0_105561700_18605_match_list "$@"; }
