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

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

is_int () {
    [[ ${1} =~ ^[+-]?[0-9]+$ ]]
}

is_float () {
    [[ ${1} =~ ^[+-]?[0-9]+\.[0-9]+$ ]]
}

is_hex () {
    [[ ${1} =~ ^[0-9a-fA-F]+$ ]]
}

is_octal () {
    [[ ${1} =~ ^[0-7]+$ ]]
}

is_number () {
    is_int "${1}" || is_float "${1}" || is_hex "${1}" || is_octal "${1}"
}

is_string () {
    ! is_number "${1}"
}

is_special () {
    [[ ! ${1} =~ [[:xdigit:]] ]]
}

contains () {
    [[ ${1} == *"$2"* ]]
}

starts_with () {
    [[ ${1} == "$2"* ]]
}

ends_with () {
    [[ ${1} == *"$2" ]]
}

is_hexcolor () {
    [[ ${1} =~ ^#?([A-Fa-f0-9]{3}){1,2}$ ]]
}

is_bool () {
    case ${1,,} in
        true|false|0|1) return 0 ;;
        *)              return 1 ;;
    esac
}

is_true () {
    case ${1,,} in
        true|1) return 0 ;;
        *)      return 1 ;;
    esac
}

is_false () {
    case ${1,,} in
        false|0) return 0 ;;
        *)       return 1 ;;
    esac
}

is_valid_address () {
    local regex='^[a-zA-Z0-9!#$%&'\''*+/=?^_`{|}~-]+(\.[a-zA-Z0-9!#$%&'\''*+/=?^_`{|}~-]+)*@([a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?$'
    [[ $1 =~ $regex ]]
}

is_valid_domain () {
    [ -n "$(dig +short MX "${1}")" ]
}

is_mail () {
    local address="$1"
    local domain="${1#*@}"

    if ! is_valid_address "${address}"; then
        echo "$(eval_gettext "invalid address:") ${address}"
        return 1
    fi

    if ! is_valid_domain "${domain}"; then
        echo "$(eval_gettext "domain:") ${domain} $(eval_gettext "unreachable")"
        return 1
    fi

    return 0
}

prog_exists () {
    local dependency="${1}"
    local program="${2}"
    local dep_return=1

    if [[ -z "$(loop "${PATH}" "${dependency}")" ]]; then
        echo "$(eval_gettext "${dependency} not found, ${program} will not work.")"
        return 1
    fi

    return 0
}

case ${1} in
    n)  is_number "${2}"        ;;
    i)  is_int "${2}"           ;;
    f)  is_float "${2}"         ;;
    h)  is_hex "${2}"           ;;
    o)  is_octal "${2}"         ;;
    hc) is_hexcolor "${2}"      ;;
    s)  is_string "${2}"        ;;
    p)  is_special "${2}"       ;;
    c)  contains "${2}" "${3}"      ;;
    sw) starts_with "${2}" "${3}"   ;;
    ew) ends_with "${2}" "${3}"     ;;
    b)  is_bool "${2}"          ;;
    bt) is_true "${2}"          ;;
    bf) is_false "${2}"         ;;
    P)  prog_exists "${2}" "${3}"   ;;
    m)  check P "dig" "'check m'" && is_mail "${2}" ;;

    *)
        bashstyle-help -a "Christopher Roy Bratusek" -e "nano@jpberlin.de" -h "https://www.nanolx.org/"\
                -l "GNU GPL v3" -n "check" -s "$(eval_gettext "additional test functions")"\
                -v "${BSNG_VERSION}" -y "${BSNG_YEAR}"\
                -o "$(eval_gettext "n:4 [4[,.]4]|check if arg is any number")"\
                -o "$(eval_gettext "i:4|check if arg is integer")"\
                -o "$(eval_gettext "f:4[,.]4|check if arg is float")"\
                -o "$(eval_gettext "h:301DE8|check if arg is hex")"\
                -o "$(eval_gettext "o:24|check if arg is octal")"\
                -o "$(eval_gettext "hc:[#]FFFFFF|check if arg is valid hex color")"\
                -o "$(eval_gettext "s:test|check if arg is a string")"\
                -o "$(eval_gettext "p:+|check if arg is special character")"\
                -o "$(eval_gettext "c:testabc abc|check if arg1 contains arg2")"\
                -o "$(eval_gettext "sw:testabc t|check if arg1 starts with arg2")"\
                -o "$(eval_gettext "ew:14235 235|check if arg1 ends with arg2")"\
                -o "$(eval_gettext "b:\${VAR}|check if arg is a boolean")"\
                -o "$(eval_gettext "bt:\${VAR}|check if arg is boolean true")"\
                -o "$(eval_gettext "bf:\${VAR}|check if arg is boolean false")"\
                -o "$(eval_gettext "P:dep prog|check if dependency of program exists")"\
                -o "$(eval_gettext "m:test@dom.tld|check if arg is valid mail address")"
    ;;
esac
