#!/bin/sh

set -e

if [ -z "$1" ] ; then
	nom="`basename "$0"`"
	cat << TERMINE
# $nom
# Assistant à darcs push pour le FTP
# © 2005 Guillaume Outters

Utilisation: $nom [-i] ftp://compte:mdp@serveur/chemin
  -i: initialiser pour Darcs
L'utilisation habituelle de l'utilitaire est:
$0 -i ftp://compte:mdp@serveur/chemin
export DARCS_APPLY_FTP="$0"
darcs push -a ftp://compte:mdp@serveur/chemin
TERMINE
	exit 1
fi

if [ "x$1" = x-i ] ; then
	shift
	mkdir -p /tmp/$$
	cd /tmp/$$
	darcs init
	serveur="`echo "$1" | cut -d / -f 1-3`"
	dossier="`echo "$1" | cut -d / -f 4-`"
	lftp -c "open $1;mkdir -p $dossier;mirror -R . $dossier"
	rm -R /tmp/$$
	exit 0
fi

mkdir /tmp/$$

cd /tmp/$$

### Fonctions ###

# Prend en entrée standard une suite de rustines, et en case une par fichier.
# Paramètres:
#   $1: suffixe des fichiers
semer()
{
	awk 'BEGIN{a=0}/^\[/{++a;fichier="'"/tmp/$$/"'"sprintf("%8.8d",a)".'"$1"'"}{if(fichier){print $0 > fichier}}/^}/{close(fichier);fichier=0}'
}

nomRustine()
{
	awk '{print substr($0,2,length-1);exit}'
}

auteurRustine()
{
	awk 'NR == 2{sub(/\*\*[^*]*$/,"");print $0;exit}'
}

dateRustine()
{
	awk 'NR == 2{sub(/^.*\*\*/,"");print $0;exit}'
}

# Paramètres:
#   $1: fichier contenant la rustine
sha1Rustine()
{
	( echo -n "`nomRustine < "$1"``auteurRustine < "$1"``dateRustine < "$1"`" ; awk '/^\]/{exit}NR == 3,/^\]/{printf("%s",substr($0,2,length-1))}' < "$1" ; echo -n f ) | openssl sha1
}

echo "Composition des rustines…" >&2

### Découpage en fichiers multiples ###

semer rustine

### Compression et nommage des fichiers ###

for fichier in *.rustine ; do
	# Règle de nommage de la rustine (cf. make_filename dans PatchInfo.lhs):
	# date (aaaammjjhhmmss)
	# 5 premiers caractères du sha1 de l'auteur
	# sha1 de (nom de la rustine, auteur, date, chacune des lignes de
	#   commentaire, 't' si la rustine est une inverse sinon 'f', le tout collé
	#   (sans retour à la ligne ni espace entre)).
	# À FAIRE: si on peut sous darcs avoir certains de ces éléments multilignes,
	# voir comment ça se présente dans le fichier rustine et s'adapter.
	gzip < "$fichier" > "`dateRustine < "$fichier"`-`auteurRustine < "$fichier" | tr -d '\012' | openssl sha1 | cut -c 1-5`-`sha1Rustine "$fichier"`.gz"
	# Question: je considère toujours 'inv' false (le f ajouté en dernière
	# minute). Il ne faudrait sans doute pas.
done

### Recopie sur le serveur ###

# À FAIRE: implémenter la création de fichiers-verrous sur le serveur FTP. Pour
# le moment on croise les doigts pour qu'un seul développeur y touche à la fois.

echo "Récupération de la dernière version du serveur…" >&2
lftp -c 'open '"$1"' ; cd _darcs ; get inventory'
# On regarde dans l'inventory ce qui est déjà là. Pour je-ne-sais quelle étrange
# raison, on a droit en entrée standard à l'ensemble des patches. Peut-être une
# erreur dans la récupération de l'inventory qui fait que darcs croit devoir
# tout envoyer. Mais si on suit sa volonté, on va se retrouver avec deux fois
# certaines rustines, ce qui n'est pas bon du tout.
semer deja < inventory
for fichier in *.deja ; do
	sha1Rustine "$fichier"
done >> liste
nActuels=`wc -l < liste`
for fichier in *.rustine ; do
	[ `( cat liste ; sha1Rustine "$fichier" ) | sort -u | wc -l` -ne $nActuels ] && echo Ajout de "`nomRustine < "$fichier"`" >&2 && awk '/^\]/{print "]";exit}{print $0}' < "$fichier"
done >> inventory
echo "Envoi des modifications…" >&2
lftp -c 'open '"$1"' ; cd _darcs ; put inventory ; cd patches ; mput *.gz'

rm -Rf /tmp/$$
