#!/bin/bash
################################################################################
# This file is distributed under the GNU All-Permissive License.
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved.
# This file is offered as-is, without any warranty.
################################################################################

# machine architecture: "x86_64-linux-gnu", "arm-linux-gnueabihf", etc.
MACHINE=$(gcc -dumpmachine)

# ldc2, gdc, dmd
DC=$1
# include-path, library-path, debug-options, release-options, shared-options
REQUEST=$2
# soname for shared library
SONAME=$3

GCC_VERSION=$(gcc -dumpversion)

# Receives a sequence of elements and one value (last argument) for comparison,
# prints TRUE if the value is found, else FALSE
Can_Find() {
    elem="${@:$#}"
    for arg in ${@:1:$#-1}; do
        if [[ "$elem" == "$arg" ]]; then
            echo TRUE
            return
        fi
    done
    echo FALSE
}


Check_Compiler() {
    COMPILER_PATH=$(which $DC)
    if [[ -z "$COMPILER_PATH" ]]; then
        echo "${DC}: compiler not found. Exit..."
        exit 1
    fi
}
Check_Compiler


# Creates DISTR_MODE (equal to DEB, RPM, ARCH of DEFAULT)
Define_Distr_Mode() {
    INFOFILE="/etc/os-release"
    if [[ ! -e "$INFOFILE" ]]; then
        DISTR_MODE=DEFAULT
        return
    fi

    DISTR_FAMILY=""
    DISTR_MODE=""

    ID=$(grep -e "^ID=" "$INFOFILE" | cut -c4- | tr -d '"')
    ID_LIKE=$(grep -e "^ID_LIKE=" "$INFOFILE" | cut -c9- | tr -d '"')
    IFS=" " read -ra ID_LIKE_ARR <<< "$ID_LIKE"

    if [[ "$ID" == debian ]]; then
        DISTR_FAMILY=debian
        DISTR_MODE=DEB
    elif [[ "$ID" == arch ]]; then
        DISTR_FAMILY=arch
        DISTR_MODE=ARCH
    elif [[ "$ID" == fedora ]]; then
        DISTR_FAMILY=fedora
        DISTR_MODE=RPM
    else
        # ID_LIKE can contain "manjaro arch", "opensuse suse"...
        if [[ `Can_Find ${ID_LIKE_ARR[@]} debian` == TRUE ]]; then
            DISTR_FAMILY=debian
            DISTR_MODE=DEB
        elif [[ `Can_Find ${ID_LIKE_ARR[@]} arch` == TRUE ]]; then
            DISTR_FAMILY=arch
            DISTR_MODE=ARCH
        elif [[ `Can_Find ${ID_LIKE_ARR[@]} suse` == TRUE ]]; then
            DISTR_FAMILY=suse
            DISTR_MODE=RPM
        elif [[ `Can_Find ${ID_LIKE_ARR[@]} fedora` == TRUE ]]; then
            DISTR_FAMILY=fedora
            DISTR_MODE=RPM
        fi
    fi

    if [[ -z $DISTR_MODE ]]; then
        DISTR_MODE=DEFAULT
    fi
}
Define_Distr_Mode  # create DISTR_MODE


# Library directory
DEFAULT_LIB_DIR=lib
DEB_LIB_DIR=lib/${MACHINE}
RPM_LIB_DIR=lib
[[ $(getconf LONG_BIT) == 64 ]] && RPM_LIB_DIR=lib64

GCC_LIB_DIR=lib/gcc/${MACHINE}/${GCC_VERSION}
if [[ "$DISTR_FAMILY" == "suse" ]]; then
    GCC_LIB_DIR=${RPM_LIB_DIR}/gcc/${MACHINE}/${GCC_VERSION}
fi

# ldc2 paths
DEFAULT_LDC2_INC_DIR="include/d"
DEB_LDC2_INC_DIR="lib/ldc/${MACHINE}/include/d"  # Debian, Ubuntu
RPM_LDC2_INC_DIR=$DEFAULT_LDC2_INC_DIR           # Fedora, openSUSE
ARCH_LDC2_INC_DIR="include/dlang/ldc"            # ArchLinux, Manjaro
# ldc2 flags
LDC2_DEBUG_OPTIONS="-d-debug --gc"
LDC2_SHLIB_OPTIONS="-shared -soname ${SONAME} -link-defaultlib-shared"
LDC2_OPTIM_OPTIONS="-O -release --gc"
LDC2_OPTIM_DEBUG_OPTIONS="-O --release -g --gc"
LDC2_EXTERNAL="-L-lgio-2.0 -L-lglib-2.0"
LDC2_EXTERNAL_ST="-L-l:libgio-2.0.a -L-l:libglib-2.0.a"
LDC2_EXTERNAL_ST+=" -L-l:libsysprof-capture-4.a -L-l:libgobject-2.0.a"
LDC2_LPATH_OPT="-L-L"
LDC2_LNAME_OPT="-L-l"

# dmd paths
DEFAULT_DMD_INC_DIR="include/dmd"
ARCH_DMD_INC_DIR="include/dlang/dmd"  # ArchLinux, Manjaro
# dmd flags
DMD_DEBUG_OPTIONS="-debug -g -gs"
DMD_SHLIB_OPTIONS="-fPIC -shared -L-soname=${SONAME} -defaultlib=libphobos2.so"
DMD_OPTIM_OPTIONS="-O -release"
DMD_OPTIM_DEBUG_OPTIONS="-O -release -g -gs"
DMD_EXTERNAL="-L-lgio-2.0 -L-lglib-2.0"
DMD_EXTERNAL_ST="-L-l:libgio-2.0.a -L-l:libglib-2.0.a"
DMD_EXTERNAL_ST+=" -L-l:libsysprof-capture-4.a -L-l:libgobject-2.0.a"
DMD_LPATH_OPT="-L-L"
DMD_LNAME_OPT="-L-l"

# gdc paths
DEFAULT_GDC_INC_DIR="${GCC_LIB_DIR}/include/d"

# gdc flags
GDC_DEBUG_OPTIONS="-fPIC -fdebug"
GDC_SHLIB_OPTIONS="-shared -Wl,-soname,${SONAME} -shared-libphobos -fPIC"
GDC_OPTIM_OPTIONS="-fPIC -O2"
GDC_OPTIM_DEBUG_OPTIONS="-fPIC -g -O2 -fno-omit-frame-pointer"
GDC_EXTERNAL="-lgio-2.0 -lglib-2.0"
GDC_EXTERNAL_ST="-l:libgio-2.0.a -l:libglib-2.0.a"
GDC_EXTERNAL_ST+=" -l:libsysprof-capture-4.a"
GDC_LPATH_OPT="-L"
GDC_LNAME_OPT="-l"


Print_Inc_Dir() {
    INC_DIR=$(eval echo \$${DISTR_MODE}_${DC^^}_INC_DIR)
    if [[ -z ${INC_DIR} ]]; then
        INC_DIR=$(eval echo \$DEFAULT_${DC^^}_INC_DIR)
    fi
    echo ${INC_DIR}
}


Print_Lib_Dir() {
    LIB_DIR="$(eval echo \$${DISTR_MODE}_LIB_DIR)"
    [[ -z ${LIB_DIR} ]] && LIB_DIR="${DEFAULT_LIB_DIR}"
    echo ${LIB_DIR}
}


Print_Flags() {
    FLAGS=""
    case "${REQUEST}" in
        "shared_options")  FLAGS=$(eval echo \$${DC^^}_SHLIB_OPTIONS) ;;
        "external_libs") FLAGS=$(eval echo \$${DC^^}_EXTERNAL)      ;;
        "external_libs_static")
            GIO_ST="libgio-2.0.a"
            GIO_ST_PATH=$(whereis "$GIO_ST" | cut -d: -f2 | sed 's/^ //')
            GLIB_ST="libgio-2.0.a"
            GLIB_ST_PATH=$(whereis "$GLIB_ST" | cut -d: -f2 | sed 's/^ //')
            if [[ "$GIO_ST_PATH" != "" && "$GLIB_ST_PATH" != "" ]]; then
                FLAGS=$(eval echo \$${DC^^}_EXTERNAL_ST)
            else
                FLAGS=$(eval echo \$${DC^^}_EXTERNAL)
            fi
            ;;
        "debug_options")   FLAGS=$(eval echo \$${DC^^}_DEBUG_OPTIONS) ;;
        "release_options") FLAGS=$(eval echo \$${DC^^}_OPTIM_OPTIONS) ;;
        "reldeb_options")  FLAGS=$(eval echo \$${DC^^}_OPTIM_DEBUG_OPTIONS) ;;
        "libpath_opt")     FLAGS=$(eval echo \$${DC^^}_LPATH_OPT)     ;;
        "libname_opt")     FLAGS=$(eval echo \$${DC^^}_LNAME_OPT)     ;;
        *) ;;
    esac
    echo "${FLAGS}"
}


Print_Compiler_Info() {
    if [[ $DC == ldc2 ]]; then
        $DC --version | head -2 | tr -d '\n' | tr -s ' '
    elif [[ $DC == gdc ]]; then
        GDC_VERSION=$(gdc --version | head -1)
        REL_DMD=$(gdc -v unknown.d 2>&1 | grep v2.1 | awk '{print $2}')
        echo "$GDC_VERSION": based on DMD "$REL_DMD"
    else
        $DC --version | head -1
    fi
}


case "${REQUEST}" in
    "include_path")  Print_Inc_Dir ;;
    "library_path")  Print_Lib_Dir ;;
    "compiler_info") Print_Compiler_Info ;;
    *)               Print_Flags   ;;
esac
