# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
##@require instinc/wobase

######################################################################
# Informations sur des bundles

function dump_frameworks() {
    # Afficher les frameworks utilisés par une application
    if [ "$SYSTEM_NAME" == "Darwin" ]; then
        clspth="$APP_MACOSCLSPTH"
    else
        clspth="$APP_UNIXCLSPTH"
    fi
    cat "$1/$clspth" | nl2lf | grep '\.framework' | grep -v "^#" | grep -v "APPROOT/" | grep -v "WOROOT/" | awk '
{
    if (match($0, /[^\/]*\.framework/) != 0) {
        print substr($0, RSTART, RLENGTH)
    }
}' | sort -u
}

function get_app_winclspth() {
    # calculer la valeur de APP_WINCLSPTH pour l'application $1
    if [ -f "$1/$APP_WINCLSPTH" ]; then
        echo "$APP_WINCLSPTH"
    else
        local clspth
        array_from_lines clspth "$(list_files "$1/$APP_WINCLSPTHDIR" | grep -i clsspath.txt)"
        if [ ${#clspth[*]} -eq 1 ]; then
            echo "$APP_WINCLSPTHDIR/$clspth"
        else
            echo "$APP_WINCLSPTH"
        fi
    fi
}

######################################################################
# Correction de bundles

function verifix_bundle() {
    # vérifier et corriger le bundle $1. Pour une application, on vérifie que le
    # script est exécutable. Pour un framework, on vérifie que le framework est
    # conforme au modèle des framework générés par WebObjects.
    local bundir="$1"
    if is_woappdir "$bundir"; then
        local script="$bundir/$(basename "$bundir" .woa)"
        if [ ! -x "$script" ]; then
            chmod +x "$script"
        fi

    elif is_wofwdir "$bundir"; then
        [ -L "$bundir/Resources" ] && return

        local filename

        if [ ! -L "$bundir/Resources" ]; then
            rm -rf "$bundir/Versions/A/Resources"
            mkdir -p "$bundir/Versions/A/Resources"
            list_all "$bundir/Resources" | while read filename; do
                cp_R "$bundir/Resources/$filename" "$bundir/Versions/A/Resources"
            done
            rm -rf "$bundir/Resources"
        fi
        if [ ! -L "$bundir/WebServerResource" ]; then
            rm -rf "$bundir/Versions/A/WebServerResources"
            mkdir -p "$bundir/Versions/A/WebServerResources"
            list_all "$bundir/WebServerResources" | while read filename; do
                cp_R "$bundir/WebServerResources/$filename" "$bundir/Versions/A/WebServerResources"
            done
            rm -rf "$bundir/WebServerResources"
        fi
        local cwd="$(pwd)"
        cd "$bundir/Versions"
        if [ -e Current ]; then
            if [ ! -L Current -a -d Current ]; then
                rm -rf Current
            else
                rm -f Current
            fi
        fi
        ln -s A Current
        cd ..
        ln -s Versions/Current/Resources Resources
        ln -s Versions/Current/WebServerResources WebServerResources
        cd "$cwd"
    fi
}

function add_framework() {
    # ajouter le framework $2 (nom de base ou chemin absolu) à l'application
    # dans le répertoire $1
    local bundir="$1" framework="$2" frameworks jars jar line
    local app_winclspth="$(get_app_winclspth "$bundir")"

    endswith "$framework" .framework || framework="$framework.framework"
    array_from_lines frameworks "$(dump_frameworks "$bundir")"
    if ! array_contains frameworks "$framework"; then
        if beginswith "$framework" /; then
            # on a donné un chemin absolu
            array_from_lines jars "$(list_files "$framework/$FW_SRVJAVADIR" "*.jar")"
            if [ -z "${jars[*]}" ]; then
                eerror "Impossible de trouver les fichiers du framework $framework
dans $WOFRAMEWORKS"
            else
                for jar in "${jars[@]}"; do
                    line="$framework/$FW_SRVJAVADIR/$jar"
                    echo "$jar" >>"$bundir/$APP_UNIXCLSPTH"
                    echo "$jar" >>"$bundir/$APP_MACOSCLSPTH"
                    echo "${jar//\//\\}" >>"$bundir/$app_winclspth"
                done
            fi
        else
            # on a donné juste le nom du framework
            array_from_lines jars "$(list_files "$WOFRAMEWORKS/$framework/$FW_SRVJAVADIR" "*.jar")"
            if [ -z "${jars[*]}" ]; then
                eerror "Impossible de trouver les fichiers du framework $framework
dans $WOFRAMEWORKS"
            else
                for jar in "${jars[@]}"; do
                    line="LOCALROOT/Library/WebObjects/Applications/Frameworks/$framework/$FW_SRVJAVADIR/$jar"
                    echo "$line" >>"$bundir/$APP_UNIXCLSPTH"
                    echo "$line" >>"$bundir/$APP_MACOSCLSPTH"
                    echo "${line//\//\\}" >>"$bundir/$app_winclspth"
                done
            fi
        fi
    fi
}

function searchreplace_classpath() {
    # Dans les fichiers classpath de l'application $1, remplacer $2 par $3. Si
    # $3 est vide, la ligne est supprimée
    local bundir="$1" search="$2" replace="$3" scriptunx scriptwin
    local app_winclspth="$(get_app_winclspth "$bundir")"

    [ -n "$search" ] || return 1
    search="${search//\//\\/}"; replace="${replace//\//\\/}"
    if [ -n "$replace" ]; then
        scriptunx="s/${search}/${replace}/g"
    else
        scriptunx="/${search}/d"
    fi
    search="${search//\\\//\\\\}"; replace="${replace//\\\//\\\\}"
    if [ -n "$replace" ]; then
        scriptwin="s/${search}/${replace}/g"
    else
        scriptwin="/${search}/d"
    fi

    nl2lf "$bundir/$APP_UNIXCLSPTH"; sedi "$scriptunx" "$bundir/$APP_UNIXCLSPTH"
    nl2lf "$bundir/$APP_MACOSCLSPTH"; sedi "$scriptunx" "$bundir/$APP_MACOSCLSPTH"
    nl2lf "$bundir/$app_winclspth"; sedi "$scriptwin" "$bundir/$app_winclspth"; nl2crlf "$bundir/$app_winclspth"
}

function remove_framework() {
    # supprimer le framework $2 (nom de base) de l'application dans le
    # répertoire $1
    local bundir="$1" framework="$2" frameworks

    endswith "$framework" .framework || framework="$framework.framework"
    array_from_lines frameworks "$(dump_frameworks "$bundir")"
    if array_contains frameworks "$framework"; then
        searchreplace_classpath "$bundir" "$framework/"
    fi
}

function fix_jars_case() {
    # Vérifier que la casse des jars de tous les frameworks utilisés par
    # l'application $1 est conforme au système de fichier
    local bundir="$1" clspth jars jar fwdir fwname jarname jarnamefs
    if [ "$SYSTEM_NAME" == "Darwin" ]; then
        clspth="$APP_MACOSCLSPTH"
    else
        clspth="$APP_UNIXCLSPTH"
    fi
    array_from_lines jars "$(cat "$bundir/$clspth" | nl2lf | grep '\.framework' | grep -v "^#" | grep -v "APPROOT/" | grep -v "WOROOT/" | awk '
{
    if (match($0, /[^\/]*\.framework/) != 0) {
        print
    }
}' | sort -u)"
    for jar in "${jars[@]}"; do
        ! endswith "$jar" .jar && ! endswith "$jar" .zip && continue

        if beginswith "$jar" LOCALROOT; then
            fwname="${jar##*/Frameworks/}"; fwname="${fwname%%/*}"
            fwdir="$WOFRAMEWORKS"
        else
            fwdir="${jar%/*.framework/*}"
            fwname="${jar##/*.framework/}";
            fwname="${jar:0:$((${#jar}-${#fwname}-1))}"; fwname="${fwname##*/}"
        fi
        jarname="${jar##*/}"

        if [ ! -d "$fwdir/$fwname" ]; then
            eerror "$(basename "$bundir"): $fwname: ce framework n'existe pas"
            continue
        fi

        array_from_lines jarnamefs "$(list_files "$fwdir/$fwname/$FW_SRVJAVADIR" "*.jar" | grep -i "$jarname")"
        if [ ${#jarnamefs[*]} -eq 0 ]; then
            eerror "$(basename "$bundir"): $fwname: $jarname n'existe pas"
        elif [ ${#jarnamefs[*]} -gt 1 ]; then
            eerror "$(basename "$bundir"): $fwname: il existe plusieurs jars $jarname"
        else
            if [ "$jarname" != "$jarnamefs" ]; then
                einfo "$(basename "$bundir"): $fwname: $jarnamefs"
                searchreplace_classpath "$bundir" "$fwname/$FW_SRVJAVADIR/$jarname" "$fwname/$FW_SRVJAVADIR/$jarnamefs"
            fi
        fi
    done
}
