#!/bin/bash
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8

function display_help() {
    uecho "$scriptname: générer un fichier $NAME

USAGE
    $scriptname [options]

OPTIONS
    -t TEMPLATE
        Indiquer le modèle de fichier à utiliser pour la génération. Les valeurs
        valides sont:
            ${TEMPLATES[*]}
    -e, --edit
    -g, --no-edit
        Editer (resp. ne pas éditer) le fichier après l'avoir généré.
        Par défaut, l'éditeur n'est pas lancé après la génération.
    -f, --overwrite
        Ecraser le fichier s'il existe déjà
    -E, --encoding ENCODING
        Spécifier l'encoding à utiliser pour la génération du fichier"
}

NAME=java
TEMPLATES=(javaproperties java woapi wosrc wosrccomp)
NAMES=(Properties)
EXTS=(properties java api wosrc)

if [ $# -eq 2 ]; then
    if [ "$1" == "--matches-template" ]; then
        for template in "${TEMPLATES[@]}"; do
            [ "$template" == "$2" ] && exit 0
        done
        exit 1
    elif [ "$1" == "--matches-name" ]; then
        for name in "${NAMES[@]}"; do
            [ "$name" == "$2" ] && exit 0
        done
        exit 1
    elif [ "$1" == "--matches-ext" ]; then
        for ext in "${EXTS[@]}"; do
            [ "$ext" == "$2" ] && exit 0
        done
        exit 1
    fi
fi

#source /etc/ulib || exit 1
source "$(dirname "$0")/../ulib/ulib" || exit 1
urequire DEFAULTS

function check_overwrite() {
    if [ -e "$1" -a -z "$overwrite" ]; then
        eerror "$1: refus d'écraser un fichier déjà existant (utiliser -f)"
        return 1
    fi
    return 0
}

function generate_javaproperties() {
    local file="$1"
    local encoding=iso-8859-1
    local mode=

    check_overwrite "$file" || return
    estep "$(ppath "$file")"
    echo >"$file" "# -*- coding: $encoding ${mode:+mode: $mode }-*- vim:sw=4:sts=4:et:ai:si:sta:fenc=$encoding"
    [ -n "$2" ] && array_add "$2" "$file"
    return 0
}

function guess_package() {
    local dir="$(abspath "$1")"
    local -a files
    local file
    array_lsfiles files "$dir" "*.java"
    if [ ${#files[*]} -gt 0 ]; then
        # récupérer le package dans un fichier existant
        file="${files[0]}"
        awk <"$file" '
/^[ \t]*package[ \t]/ {
  if (match($0, /[ \t]*package[ \t]*(.*)[ \t]*;/, vs) != 0) {
    print vs[1];
    exit 0
  }
}
# stop quand on arrive à import ou class
/^(import|class)/ { exit 0 }'
    elif [[ "$dir" == */src/main/java/* ]]; then
        local package="${dir##*/src/main/java/}"
        package="${package//\//.}"
        echo "$package"
    elif [[ "$dir" == */Sources/* ]]; then
        local package="${dir##*/Sources/}"
        package="${package//\//.}"
        echo "$package"
    fi
}

function generate_java() {
    local file="$1"
    local dir="$(dirname "$file")"
    local name="$(basename "$file")"
    local basename="${name%.*}"
    local mode=

    [ -n "$package" ] || local package="$(guess_package "$dir")"
    local packline
    [ -n "$package" ] && packline="package $package;"
    local -a implines
    for import in "${imports[@]}"; do
        array_add implines "import $import;"
    done
    implines="$(array_to_lines implines)"
    local exts
    [ -n "$extends" ] && exts=" extends $extends"
    local impls
    if [ "${#implements[*]}" -gt 0 ]; then
        impls=" implements $(array_join implements ", ")"
    fi

    check_overwrite "$file" || return
    estep "$(ppath "$file")"
    cat >"$file" <<EOF
/* -*- coding: $encoding ${mode:+mode: $mode }-*- vim:sw=4:sts=4:et:ai:si:sta:fenc=$encoding
 * $name
 * Créé le $(date +%d/%m/%Y)
 */
${packline:+$packline
}${implines:+
$implines
}
/**
 * @author $USER
 */
public class $basename${exts}${impls} {
${body:+$body
}}
EOF
    [ -n "$2" ] && array_add "$2" "$file"
    return 0
}

function generate_woapi() {
    local file="$1"
    local dir="$(dirname "$file")"
    local name="$(basename "$file")"
    local basename="${name%.*}"
    local encoding=utf-8

    check_overwrite "$file" || return
    estep "$(ppath "$file")"
    cat >"$file" <<EOF
<?xml version="1.0" encoding="$encoding" standalone="yes"?>
<wodefinitions>
    <wo wocomponentcontent="false" class="$basename">
    </wo>
</wodefinitions>
EOF
    [ -n "$2" ] && array_add "$2" "$file"
    return 0
}

function generate_wosrc() {
    local file="$1"

    local dtattr
    [ -n "$doctype" ] && dtattr=" doctype=\"$doctype\""

    check_overwrite "$file" || return
    estep "$(ppath "$file")"
    cat >"$file" <<EOF
<?sox encoding="$encoding"$dtattr namespaces="wo,wo.qattrs" modeline="-*- coding: $encoding -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=$encoding"?>
EOF
    if [ -n "$html" ]; then
        cat >>"$file" <<EOF
html>
	head>
		title>
	body>
		h1>
EOF
    elif [ -n "$blueprint" ]; then
        cat >>"$file" <<EOF
wo:blueprintm> menu="menu" q:title=""
EOF
    elif [ -n "$bootstrap" ]; then
        cat >>"$file" <<EOF
wo:bspagem> menu="menu" q:title=""
EOF
    fi
    [ -n "$2" ] && array_add "$2" "$file"
    return 0
}

function generate_wosrccomp() {
    local file="$(abspath "$1")"
    local dir="$(dirname "$file")"
    local name="$(basename "$file")"
    local basename="${name%.*}"
    local ext="${name##*.}"
    case "$ext" in
    wosrc|api|java|"") file="$dir/$basename";;
    *) die "Destination name should not have an extension"
    esac

    local prefix
    case "$file" in
    */src/main/java/*/v/*)
	javafile="$file"
        prefix="${file%%/src/main/java/*}"
        wosrcfile="${javafile#$prefix/}"
        prefix="$prefix/src/main/wosrc"
	wosrcfile="${wosrcfile#*/v/}"
        wosrcfile="$prefix/$wosrcfile"
	;;
    */src/main/java/*)
	javafile="$file"
	wosrcfile="${file/src\/main\/java/src/main/wosrc}"
	;;
    */src/main/wosrc/*)
	wosrcfile="$file"
	javafile="${file/src\/main\/wosrc/src/main/java}"
	;;
    *)
	wosrcfile="$file"
	javafile="$file"
	;;
    esac

    etitle "$(ppath "$file")"
    mkdirof "$wosrcfile"
    generate_wosrc "$wosrcfile.wosrc"; [ -n "$2" ] && array_add "$2" "$wosrcfile.wosrc"
    generate_woapi "$wosrcfile.api"; [ -n "$2" ] && array_add "$2" "$wosrcfile.api"
    local -a imports implements
    local extends body
    imports=(com.webobjects.appserver.WOComponent com.webobjects.appserver.WOContext)
    extends=WOComponent
    implements=()
    body="\
    private static final long serialVersionUID = 1L;

    public ${basename}(WOContext context) {
        super(context);
    }"
    mkdirof "$javafile"
    generate_java "$javafile.java"; [ -n "$2" ] && array_add "$2" "$javafile.java"
    eend
    return 0
}

template=
edit=
overwrite=
encoding=
package=
imports=()
extends=
implements=()
body=
doctype=
html=
blueprint=
bootstrap=1
parse_opts "${PRETTYOPTS[@]}" \
    --help '$exit_with display_help' \
    -t:,--template: template= \
    -e,--edit edit=1 \
    -g,--no-edit edit= \
    -f,--overwrite overwrite=1 \
    -E:,--encoding: encoding= \
    --package: package= \
    --imports: imports \
    --extends: extends= \
    --implements: implements \
    --body: body= \
    --doctype: doctype= \
    --html '$html=1; doctype=html4; blueprint=; bootstrap=' \
    --blueprint,--bp '$blueprint=1; html=; bootstrap=' \
    --bootstrap,--bs '$bootstrap=1; html=; blueprint=' \
    @ args -- "$@" && set -- "${args[@]}" || die "$args"

[ -n "$encoding" ] || encoding=utf-8
array_fix_paths imports
array_fix_paths implements

files2edit=()
r=0
for file in "$@"; do
    t="$template"
    if [ -z "$t" ]; then
        dir="$(dirname "$file")"
        name="$(basename "$file")"
        # Si template n'est pas spécifié, le déterminer le cas échéant à partir
        # du nom de fichier. Rajouter ici le code approprié
        case "$name" in
        Properties) t=javaproperties;;
        esac
    fi

    case "$t" in
    javaproperties|properties|jprops|props) generate_javaproperties "$file" files2edit || r=$?;;
    java|j) generate_java "$file" files2edit || r=$?;;
    woapi|api) generate_woapi "$file" files2edit || r=$?;;
    wosrc) generate_wosrc "$file" files2edit || r=$?;;
    wosrccomp|wc) generate_wosrccomp "$file" files2edit || r=$?;;
    *) die "$NAME: template invalide: $t";;
    esac
done

if [ -n "$edit" -a "${#files2edit[*]}" -gt 0 ]; then
    "${EDITOR:-vi}" "${files2edit[@]}"
fi

exit $r
