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

function display_help() {
    uecho "$scriptname: synchroniser un répertoire de wiki avec un tiddlywiki

USAGE
    $scriptname [options]

Un répertoire de wiki est un répertoire où chaque page est contenu dans un
fichier avec l'extension .twp
Un tiddlywiki est un fichier html contenant le code de TiddlyWiki et les données
associées.

OPTIONS
    -d wikidir
    -f wikifile
        Spécifier le répertoire de wiki et le tiddlywiki à traiter. Par défaut,
        il s'agit de wiki.html dans le répertoire courant.
    -u  Importer les pages de wikidir dans le tiddlywiki. Utiliser cette action
        quand les pages de wikidir sont modifiées et qu'il faut mettre à jour le
        tiddlywiki.
        Il s'agit de l'action par défaut
    --force
        Forcer l'importation des pages même si les tiddlers correspondant sont
        plus récents dans le tiddlywiki
        Forcer aussi la regénération de wikifile même si aucune modification n'a
        été détectée
    -e  Exporter les tiddlers du tiddlywiki vers wikidir. Utiliser cette action
        quand le tiddlywiki a été modifié, et qu'il faut synchroniser wikidir
        avec les dernières modifications.
    -U  Mettre à jour le fichier wikifile avec la dernière version de tiddlywiki
        située dans $(ppath "$TEMPLATE")"
}

source "$(dirname "$0")/ulib/ulib" &&
urequire DEFAULTS udir tiddlywiki javaproperties ||
exit 1

TEMPLATE="$scriptdir/lib/tiddlywiki/empty.html"

function find_wikifile() {
    local -a htmls
    local wikidir="$1"
    array_from_lines htmls "$(list_files "$wikidir" "*.html")"
    case "${#htmls[*]}" in
    1) # un seul, prendre celui-là
        wikifile="$wikidir/${htmls[0]}"
        ;;
    *) # sinon, prendre le nom par défaut
        wikifile="$wikidir/wiki.html"
        ;;
    esac
    echo "$wikifile"
}

function init_wikidir() {
    # Créer les fichiers de base correspondant à un tiddlywiki vide,
    # $1(=wiki.html) étant le tiddlywiki et $2(=.) le répertoire destination
    local wikifile="$1" wikidir="${2:-.}"

    # créer le répertoire
    if [ ! -f "$wikidir/.udir" ]; then
        estep "Configuration du répertoire"
        udir_create_maybe "$wikidir"
        local set_udir_types
        set_udir_types="$(udir_eval "$wikidir" "array_set udir_types wikidir; set_array_cmd udir_types")"
        udir_update "$wikidir" "$set_udir_types"
    fi

    # calculer le nom par défaut à prendre pour le titre et le sous-titre
    local -a parentdirs
    local parentdir projtitle projsubtitle
    local tmpname tmpdesc
    parentdirs parentdirs "$wikidir/.."
    for parentdir in "${parentdirs[@]}"; do
        if [ -f "$parentdir/build.properties" ]; then
            # il faut avoir project.name et éventuellement project.desc
            read_property "$parentdir/build.properties" project.name tmpname
            read_property "$parentdir/build.properties" project.desc tmpdesc
            if [ -n "$tmpname" ]; then
                projtitle="$tmpname"
                projsubtitle="$tmpdesc"
                break
            fi
        fi
        if [ -f "$parentdir/.udir" ]; then
            # prendre udir_desc
            projtitle="$(basename "$parentdir")"
            projsubtitle="$(udir_eval "$parentdir" 'echo "$udir_desc"')"
            break
        fi
    done
    if [ -z "$projtitle" ]; then
        projtitle="$(basename "${parentdirs[0]}")"
    fi

    # créer le tiddlywiki
    [ -n "$wikifile" ] || wikifile="$wikidir/$projtitle.html"
    local created=
    if [ ! -f "$wikifile" ]; then
        estep "Copie du modèle de wiki"
        cp "$TEMPLATE" "$wikifile"
        created=1

        # créer les pages de wiki de base, seulement si on a créé le tiddlywiki
        etitle "Création des pages initiales"
        local now="$(twdate_curtid)"
        local CWD="$(pwd)"
        local TW_VERBOSE=
        cd "$wikidir"
        [ -f SiteTitle.twp ] || twwrite_twpage SiteTitle "$USER" "$USER" "$now" "" "" 1 "$projtitle"
        [ -f SiteSubtitle.twp ] || twwrite_twpage SiteSubtitle "$USER" "$USER" "$now" "" "" 1 "$projsubtitle"
        [ -f SiteUrl.twp ] || twwrite_twpage SiteUrl "$USER" "$USER" "$now" "" "" 1 ""
        [ -f MainMenu.twp ] || twwrite_twpage MainMenu "$USER" "$USER" "$now" "" "" 1 "[[GettingStarted]]"
        [ -f DefaultTiddlers.twp ] || twwrite_twpage DefaultTiddlers "$USER" "$USER" "$now" "" "" 1 "[[Main]]"
        [ -f Main.twp ] || twwrite_twpage Main "$USER" "$USER" "$now" "" "" 1 ""
        cd "$CWD"
        eend
    fi
}

action=update
wikidir=
wikifile=
delete=
force=
parse_opts "${PRETTYOPTS[@]}" \
    --help '$exit_with display_help' \
    -u action=update \
    -e action=export \
    -U action=upgrade \
    -d: wikidir= \
    -f: wikifile= \
    --delete delete=1 \
    --force force=1 \
    @ args -- "$@" && set -- "${args[@]}" || die "$args"

[ -n "$wikidir" ] || wikidir=.
[ -n "$wikifile" ] || wikifile="$(find_wikifile "$wikidir")"

if [ "$action" == "update" ]; then
    udir_eval "$wikidir" "array_contains udir_types wikidir" || {
        ask_yesno "Ce répertoire ne semble pas être un répertoire de wiki. Voulez-vous créer les fichiers de base?" O || die
    }
    # laisser init_wikidir choisir le nom du fichier s'il n'existe pas
    [ -f "$wikifile" ] || wikifile=
    init_wikidir "$wikifile" "$wikidir"
    [ -n "$wikifile" ] || wikifile="$(find_wikifile "$wikidir")"

    wikidir="$(abspath "$wikidir")"
    wikifile="$(abspath "$wikifile")"

    # exporter wikifile vers un répertoire de travail
    etitle "Création des répertoires de travail"
    estep "Pages du wikidir"
    # exporter les pages de wikidir sous forme canonique pour qu'on puisse les
    # comparer avec les fichiers extraits du tiddlywiki
    ac_set_tmpdir oldwikidir
    (
        function __twpage_data() {
            local title="$1" creator="$2" modifier="$3" created="$4" modified="$5" tags="$6" changecount="$7" content="$8"
            created="$(twdate_twp2tid "$created")"
            modified="$(twdate_twp2tid "$modified")"
            twwrite_twpage "$title" "$creator" "$modifier" "$created" "$modified" "$tags" "$changecount" "$content"
        }
        TW_VERBOSE=
        cd "$oldwikidir"
        array_from_lines twpages "$(list_files "$wikidir" "*.twp")"
        for twpage in "${twpages[@]}"; do
            eval "$(twdump_twpage "$wikidir/$twpage")"
        done
    )
    array_from_lines oldtwpages "$(list_files "$oldwikidir" "*.twp")"
    estep "Pages du tiddlywiki"
    ac_set_tmpdir newwikidir
    TW_VERBOSE= export_to_twpages "$wikifile" "$newwikidir"
    array_from_lines newtwpages "$(list_files "$newwikidir" "*.twp")"
    eend

    # Calculer les modifications
    etitle "Calcul des modifications"
    modified=
    for oldtwpage in "${oldtwpages[@]}"; do
        pagename="${oldtwpage%.twp}"
        if ! array_contains newtwpages "$oldtwpage"; then
            estep "$pagename: nouvelle page"
            cp "$oldwikidir/$oldtwpage" "$newwikidir"
            modified=1
        elif testsame "$oldwikidir/$oldtwpage" "$newwikidir/$oldtwpage"; then
            :
        elif twcheck_twpage_newtwpage "$newwikidir/$oldtwpage" "$oldwikidir/$oldtwpage"; then
            estepw "$pagename: mise à jour"
            cp "$oldwikidir/$oldtwpage" "$newwikidir"
            modified=1
        elif [ -n "$force" ]; then
            estepw "$pagename: mise à jour forcée"
            cp "$oldwikidir/$oldtwpage" "$newwikidir"
            modified=1
        else
            estepw "$pagename: tiddler non écrasé car il est plus récent dans $(ppath "$wikifile")
Utilisez -e pour mettre à jour le répertoire"
        fi
    done
    for newtwpage in "${newtwpages[@]}"; do
        pagename="${newtwpage%.twp}"
        if ! array_contains oldtwpages "$newtwpage"; then
            if [ -n "$delete" ]; then
                estepe "$pagename: suppression"
                rm "$newwikidir/$newtwpage"
                modified=1
            else
                estepw "$pagename: Ce tiddler n'existe que dans $(ppath "$wikifile")
Utilisez -e pour l'exporter ou --delete pour le supprimer"
            fi
        fi
    done
    eend

    # puis réimporter les fichiers de newwikidir dans wikifile
    if [ -n "$modified" -o -n "$force" ]; then
        etitle "Importation des tiddlers"
        import_from_twpages "$wikifile" "$newwikidir"
        eend
    fi

elif [ "$action" == "export" ]; then
    [ -f "$wikifile" ] || die "$wikifile: fichier introuvable"
    wikidir="$(abspath "$wikidir")"
    wikifile="$(abspath "$wikifile")"

    export_to_twpages "$wikifile" "$wikidir"

elif [ "$action" == "upgrade" ]; then
    [ -f "$wikifile" ] || die "$wikifile: fichier introuvable"
    wikidir="$(abspath "$wikidir")"
    wikifile="$(abspath "$wikifile")"

    theversion="$(twget_version "$wikifile")"
    srcversion="$(twget_version "$TEMPLATE")"

    if [ "$theversion" != "$srcversion" ]; then
        einfo "La version actuelle est $theversion"
        if ask_yesno "Une nouvelle version $srcversion est disponible. Faut-il l'installer?" O; then
            twupgrade "$wikifile" "$TEMPLATE"
        fi
    elif [ "$templatefile" -nt "$wikifile" ]; then
        twupgrade "$wikifile" "$TEMPLATE"
    fi
fi