#!/bin/bash
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
source "$(dirname "$0")/lib/ulib/ulib" || exit 1
urequire DEFAULTS

function display_help() {
    uecho "$scriptname: mettre à jour un module ur/* ou lib/* sans utiliser composer

ça permet de faire du développement plus rapidement sans utiliser les dépôts de
type path

USAGE
    $scriptname modules...

OPTIONS
    -n, --fake
        Afficher simplement ce qui serait fait
    -q, --quiet
        Ne pas lancer rsync en mode verbose
    -l, --link
        Transformer les clones de dépôts en liens directs vers les projets
    -k, --copy
        Transformer les liens directs vers les projets en copies des projets
    -i, --install
        Supprimer les répertoires et les faire recréer par composer i
    -j, --reinstall-link
        Supprimer les répertoires et les faire recréer par composer i,
        uniquement s'il s'agit de liens
    -u, --update
        Supprimer les répertoires et les faire recréer par composer u
    --ru, --recursive-update
        Mettre à jour de façon récursive tous les projets dépendants.
        NB: les modifications seront automatiquement enregistrées dans git."
}

fake=
verbose=1
action=
args=(
    --help '$exit_with display_help'
    -d:,--project-dir: projdir=
    -n,--fake fake=1
    -q,--quiet verbose=
    -l,--link action=link
    -k,--copy action=copy
    -i,--install action=install
    -j,--reinstall-link action=reinstall-link
    -u,--update action=update
    --ru,--recursive-update action=recursive-update
)
parse_args "$@"; set -- "${args[@]}"

if [ -d "$projdir" ]; then
    cd "$projdir"
elif [ -e "$projdir" ]; then
    die "$projdir: répertoire introuvable"
fi

found=
first=1
while true; do
    if [ -f composer.json ]; then
        found=1
        break
    fi
    first=
    cd ..
    if [ "$(pwd)" == "$HOME" ]; then
        die "Cette commande ne peut être lancée que depuis un projet Composer"
    fi
done
if [ -z "$first" ]; then
    enote "Le répertoire du projet est $(ppath . ~)"
fi

case "$action" in
install|update|reinstall-link|recursive-update)
    [ -x ./composer.phar ] || die "Impossible de trouver composer.phar"
    ;;
esac
if [ "$action" == recursive-update ]; then
    # avec recursive-update, tous les modules doivent être considérés
    set --
fi

###

if [ $# -eq 0 ]; then
    setx -a ms=list_dirs vendor "ur/*" "lib/*"
    set -- "${ms[@]}"
fi

function check_module() {
    [ -d "../$m" ] || die "$m: module introuvable"
}
function update_with_rsync() {
    local -a rsync_args
    rsync_args=(
        -a ${fake:+-n} ${verbose:+-v}
        --delete
        -f "- /.git/"
        -f "- /vendor/"
        "../$m/" "vendor/$p"
    )
    rsync "${rsync_args[@]}"
}

deps=()
modules=()
for m in "$@"; do
    m="${m#vendor/}" # pour permettre de spécifier le chemin directement
    m="${m//\//-}"
    case "$m" in
    ur-*|lib-*) ;;
    *) m="ur-$m";;
    esac
    modules+=("$m")
    p="${m//-/\/}"

    check_module
    case "$action" in
    link)
        # Ignorer les liens et transformer les copies en liens
        if [ ! -L "vendor/$p" ]; then
            link="$m"
            path="/project/vendor/$p"
            path="${path%/*}"
            while [ -n "$path" ]; do
                link="../$link"
                path="${path%/*}"
            done

            etitle "$m"
            estep "suppr. vendor/$p"
            rm -rf "vendor/$p"
            mkdirof "vendor/$p"

            estep "vendor/$p --> $link"
            ln -s "$link" "vendor/$p"
            eend
        fi
        ;;
    copy)
        # Transformer les liens en copie et les synchroniser
        etitle "$m"
        if [ -L "vendor/$p" ]; then
            estep "suppr. vendor/$p"
            rm -f "vendor/$p"
        fi
        update_with_rsync
        eend
        ;;
    install)
        # Supprimer les liens et répertoires...
        etitle "$m"
        if [ -e "vendor/$p" ]; then
            estep "suppr. vendor/$p"
            rm -rf "vendor/$p"
        fi
        array_add deps "$p"
        eend
        ;;
    reinstall-link|recursive-update)
        # Supprimer les liens uniquement...
        etitle "$m"
        if [ -L "vendor/$p" ]; then
            estep "suppr. vendor/$p"
            rm -f "vendor/$p"
        fi
        array_add deps "$p"
        eend
        ;;
    update)
        # Supprimer les liens et répertoires...
        etitle "$m"
        if [ -e "vendor/$p" ]; then
            estep "suppr. vendor/$p"
            rm -rf "vendor/$p"
        fi
        array_add deps "$p"
        eend
        ;;
    *)
        # Action par défaut: ignorer les liens et synchroniser les copies
        if [ ! -L "vendor/$p" ]; then
            etitle "$m"
            update_with_rsync
            eend
        fi
        ;;
    esac
done

case "$action" in
install|reinstall-link)
    # ... puis installer les dépendances
    etitle "Installation des dépendances"
    ./composer.phar i
    eend
    ;;
update)
    # ... puis mettre à jour les dépendances
    etitle "Mise à jour des dépendances"
    ./composer.phar u "${deps[@]}"
    eend
    ;;
recursive-update)
    # mettre à jour les dépendances de façon récursives
    for m in "${modules[@]}"; do
        etitle "Mise à jour récursive: $m"
        "$script" -d "../$m" --ru
        eend
    done
    estep "Maj deps"
    ./composer.phar u

    estep "Enregistrement dans git"
    pci -A "maj deps"
    ;;
esac