#!/bin/bash

#
# BBL-Archive-Clone
# Version : 0.0.6
# Author  : Charlies Lacaille / Basil Nabu
# License : MIT
#
# Usage :
# ./bbl-archive-clone.sh "URL_ARCHIVE" "URL_CIBLE" [TARIF_HORAIRE] [DOSSIER_DEPLOIEMENT] [BASE_PATH]
#

VERSION="0.0.6"

ARCHIVE_URL="$1"
TARGET_URL="$2"
HOURLY_RATE="$3"
DEPLOY_DIR="$4"
BASE_PATH="$5"

BASE_DIR="./acces-data"
START_GLOBAL=$(date +%s)

if [ -z "$ARCHIVE_URL" ] || [ -z "$TARGET_URL" ]; then
    echo "Usage : $0 <url-webarchive> <url-cible> [tarif-horaire] [dossier-deploiement] [base-path]"
    exit 1
fi

if [ -z "$HOURLY_RATE" ]; then
    HOURLY_RATE="80"
fi

TARGET_URL="${TARGET_URL%/}"
BASE_PATH="/${BASE_PATH#/}"
BASE_PATH="${BASE_PATH%/}"

if [ "$BASE_PATH" = "/" ]; then
    BASE_PATH=""
fi

PUBLIC_URL="$TARGET_URL$BASE_PATH"

SOURCE_DOMAIN=$(echo "$ARCHIVE_URL" | sed -E 's#^https://web\.archive\.org/web/[0-9]+[a-zA-Z_*/-]*/https?://([^/]+)/?.*#\1#')
ARCHIVE_DATE=$(echo "$ARCHIVE_URL" | sed -E 's#^https://web\.archive\.org/web/([0-9]+)[a-zA-Z_*/-]*/.*#\1#')
TARGET_DOMAIN=$(echo "$TARGET_URL" | sed -E 's#^https?://([^/]+)/?.*#\1#')

if [ -z "$SOURCE_DOMAIN" ] || [ "$SOURCE_DOMAIN" = "$ARCHIVE_URL" ]; then
    echo "Erreur : impossible d'extraire le domaine source."
    exit 1
fi

WORK_DIR="$BASE_DIR/$SOURCE_DOMAIN"
RAW_DIR="$WORK_DIR/raw"
CLEAN_DIR="$WORK_DIR/clean"
SITE_DIR="$WORK_DIR/site"
REPORT_DIR="$WORK_DIR/report"

LOG_FILE="$REPORT_DIR/wget.log"
REPORT_FILE="$REPORT_DIR/rapport.txt"
CSV_FILE="$REPORT_DIR/rapport.csv"
BROKEN_LIST="$REPORT_DIR/ressources-non-recuperees.txt"
WAYBACK_LIST="$REPORT_DIR/references-wayback-restantes.txt"
DUPLICATE_DOMAIN_LIST="$REPORT_DIR/domaines-dupliques.txt"
INTERNAL_PATH_LIST="$REPORT_DIR/chemins-internes-restants.txt"

PHASE_NAMES=()
PHASE_DURATIONS=()
PHASE_COSTS=()

phase_start()
{
    PHASE_NAME="$1"
    PHASE_START=$(date +%s)
    echo ""
    echo "=== $PHASE_NAME ==="
}

phase_end()
{
    PHASE_END=$(date +%s)
    DURATION=$((PHASE_END - PHASE_START))
    COST=$(awk "BEGIN { printf \"%.2f\", ($DURATION / 3600) * $HOURLY_RATE }")

    PHASE_NAMES+=("$PHASE_NAME")
    PHASE_DURATIONS+=("$DURATION")
    PHASE_COSTS+=("$COST")

    echo "Durée : ${DURATION}s"
    echo "Coût : ${COST} €"
}

to_json_url()
{
    echo "$1" | sed 's#/#\\/#g'
}

rewrite_file()
{
    FILE="$1"
    JSON_PUBLIC_URL=$(to_json_url "$PUBLIC_URL")
    JSON_TARGET_DOMAIN=$(to_json_url "$TARGET_DOMAIN$BASE_PATH")

    # --------------------------------------------------
    # URLs Wayback classiques vers le domaine source
    # --------------------------------------------------

    perl -0pi -e "s#https?://web\.archive\.org/web/[0-9a-zA-Z_*/-]+/https?://\Q$SOURCE_DOMAIN\E(?=[:/?#\"' <>)])#$PUBLIC_URL#g" "$FILE"
    perl -0pi -e "s#/web/[0-9a-zA-Z_*/-]+/https?://\Q$SOURCE_DOMAIN\E(?=[:/?#\"' <>)])#$PUBLIC_URL#g" "$FILE"

    # --------------------------------------------------
    # URLs directes vers le domaine source
    # Important :
    # on exige une frontière après le domaine.
    # Cela évite de réécrire rootstravel.com dans
    # rootstravel.com.babylon-project.fr.
    # --------------------------------------------------

    perl -0pi -e "s#https://\Q$SOURCE_DOMAIN\E(?=[:/?#\"' <>)])#$PUBLIC_URL#g" "$FILE"
    perl -0pi -e "s#http://\Q$SOURCE_DOMAIN\E(?=[:/?#\"' <>)])#$PUBLIC_URL#g" "$FILE"
    perl -0pi -e "s#//\Q$SOURCE_DOMAIN\E(?=[:/?#\"' <>)])#//$TARGET_DOMAIN$BASE_PATH#g" "$FILE"

    # --------------------------------------------------
    # URLs Wayback génériques restantes
    # --------------------------------------------------

    perl -0pi -e "s#https?://web\.archive\.org/web/[0-9a-zA-Z_*/-]+/##g" "$FILE"
    perl -0pi -e 's#https?://web\.archive\.org[^"'\'' <>)]+##g' "$FILE"

    # --------------------------------------------------
    # URLs JSON encodées vers le domaine source
    # --------------------------------------------------

    perl -0pi -e "s#https:\\\/\\\/web\.archive\.org\\\/web\\\/[0-9a-zA-Z_*/-]+\\\/https?:\\\/\\\/\Q$SOURCE_DOMAIN\E(?=\\\/|\\\"|\\\?|\\\#)#$JSON_PUBLIC_URL#g" "$FILE"
    perl -0pi -e "s#https:\\\/\\\/\Q$SOURCE_DOMAIN\E(?=\\\/|\\\"|\\\?|\\\#)#$JSON_PUBLIC_URL#g" "$FILE"
    perl -0pi -e "s#http:\\\/\\\/\Q$SOURCE_DOMAIN\E(?=\\\/|\\\"|\\\?|\\\#)#$JSON_PUBLIC_URL#g" "$FILE"

    # --------------------------------------------------
    # URLs JSON encodées externes connues
    # --------------------------------------------------

    perl -0pi -e "s#https:\\\/\\\/web\.archive\.org\\\/web\\\/[0-9a-zA-Z_*/-]+\\\/https?:\\\/\\\/s\.w\.org#https:\\\/\\\/s.w.org#g" "$FILE"
    perl -0pi -e "s#https:\\\/\\\/web\.archive\.org\\\/web\\\/[0-9a-zA-Z_*/-]+\\\/https?:\\\/\\\/i\.imgur\.com#https:\\\/\\\/i.imgur.com#g" "$FILE"
    perl -0pi -e "s#https:\\\/\\\/web\.archive\.org\\\/web\\\/[0-9a-zA-Z_*/-]+\\\/https?:\\\/\\\/shinetheme\.com#https:\\\/\\\/shinetheme.com#g" "$FILE"

    # --------------------------------------------------
    # JS tiers modifiés par Wayback
    # --------------------------------------------------

    perl -0pi -e 's#//web\.archive\.org/web/[0-9a-zA-Z_*/-]+/https://about:blank#about:blank#g' "$FILE"
    perl -0pi -e 's#//web\.archive\.org/web/[0-9a-zA-Z_*/-]+/https://www\.youtube\.com#https://www.youtube.com#g' "$FILE"
    perl -0pi -e 's#//web\.archive\.org/web/[0-9a-zA-Z_*/-]+/https://player\.vimeo\.com#https://player.vimeo.com#g' "$FILE"
    perl -0pi -e 's#//web\.archive\.org/web/[0-9a-zA-Z_*/-]+/https://maps\.google\.#https://maps.google.#g' "$FILE"
    perl -0pi -e 's#//web\.archive\.org/web/[0-9a-zA-Z_*/-]+/https://img\.youtube\.com#https://img.youtube.com#g' "$FILE"
    perl -0pi -e 's#//web\.archive\.org/web/[0-9a-zA-Z_*/-]+/https://vimeo\.com#https://vimeo.com#g' "$FILE"
    perl -0pi -e 's#//web\.archive\.org/web/[0-9a-zA-Z_*/-]+/https://vzaar\.com#https://vzaar.com#g' "$FILE"
    perl -0pi -e 's#//web\.archive\.org/web/[0-9a-zA-Z_*/-]+/https://view\.vzaar\.com#https://view.vzaar.com#g' "$FILE"

    # --------------------------------------------------
    # Nettoyage des chemins internes accidentels
    # --------------------------------------------------

    perl -0pi -e "s#https?://\Q$TARGET_DOMAIN\E/acces-data/\Q$SOURCE_DOMAIN\E/(raw|clean|site)/\Q$SOURCE_DOMAIN\E#$PUBLIC_URL#g" "$FILE"
    perl -0pi -e "s#/acces-data/\Q$SOURCE_DOMAIN\E/(raw|clean|site)/\Q$SOURCE_DOMAIN\E##g" "$FILE"

    # --------------------------------------------------
    # Anti-doublons domaine cible
    # Exemple corrigé :
    # rootstravel.com.babylon-project.fr.babylon-project.fr
    # --------------------------------------------------

    perl -0pi -e "s#\Q$TARGET_DOMAIN\E(\.babylon-project\.fr)+#$TARGET_DOMAIN#g" "$FILE"
    perl -0pi -e "s#https://\Q$TARGET_DOMAIN\E/https://\Q$TARGET_DOMAIN\E#https://$TARGET_DOMAIN#g" "$FILE"
    perl -0pi -e "s#http://\Q$TARGET_DOMAIN\E/http://\Q$TARGET_DOMAIN\E#http://$TARGET_DOMAIN#g" "$FILE"
}

count_files()
{
    EXTENSIONS="$1"
    find "$SITE_DIR" -type f | grep -Ei "$EXTENSIONS" | wc -l
}

mkdir -p "$RAW_DIR" "$CLEAN_DIR" "$SITE_DIR" "$REPORT_DIR"

phase_start "Aspiration Web Archive"

rm -rf "$RAW_DIR"
mkdir -p "$RAW_DIR"

wget \
    -r \
    -k \
    -p \
    -E \
    -nH \
    --cut-dirs=3 \
    --no-parent \
    --convert-links \
    --adjust-extension \
    --page-requisites \
    --restrict-file-names=windows \
    --directory-prefix="$RAW_DIR" \
    --output-file="$LOG_FILE" \
    "$ARCHIVE_URL"

phase_end

phase_start "Préparation copie nettoyable"

rm -rf "$CLEAN_DIR"
mkdir -p "$CLEAN_DIR"
cp -a "$RAW_DIR/." "$CLEAN_DIR/"

phase_end

phase_start "Nettoyage Web Archive"

find "$CLEAN_DIR" -type f \( -name "*.html" -o -name "*.htm" \) | while read FILE
do
    perl -0pi -e 's#<!-- BEGIN WAYBACK TOOLBAR INSERT -->.*?<!-- END WAYBACK TOOLBAR INSERT -->##sg' "$FILE"
    perl -0pi -e 's#<div id="wm-ipp".*?</div>\s*</div>\s*</div>##sg' "$FILE"
    perl -0pi -e 's#<script[^>]+wombat\.js[^>]*></script>##sg' "$FILE"
    perl -0pi -e 's#<script[^>]+bundle-playback\.js[^>]*></script>##sg' "$FILE"
    perl -0pi -e 's#<link[^>]+banner-styles\.css[^>]*>##sg' "$FILE"
    perl -0pi -e 's#<link[^>]+iconochive\.css[^>]*>##sg' "$FILE"
    perl -0pi -e 's#<script[^>]+archive_analytics[^>]*></script>##sg' "$FILE"
done

find "$CLEAN_DIR" -type d -name "_static" -exec rm -rf {} + 2>/dev/null

phase_end

phase_start "Réécriture des URLs"

find "$CLEAN_DIR" -type f \( \
    -name "*.html" -o \
    -name "*.htm" -o \
    -name "*.css" -o \
    -name "*.js" \
\) | while read FILE
do
    rewrite_file "$FILE"
done

phase_end

phase_start "Reconstruction du site publiable"

rm -rf "$SITE_DIR"
mkdir -p "$SITE_DIR"

SOURCE_SITE_DIR=$(find "$CLEAN_DIR" -type d -name "$SOURCE_DOMAIN" | head -n 1)

if [ -n "$SOURCE_SITE_DIR" ]; then
    cp -a "$SOURCE_SITE_DIR/." "$SITE_DIR/"
else
    cp -a "$CLEAN_DIR/." "$SITE_DIR/"
fi

HOME_FILE=$(find "$SITE_DIR" -type f -name "index.html" | head -n 1)

if [ -n "$HOME_FILE" ] && [ "$HOME_FILE" != "$SITE_DIR/index.html" ]; then
    cp "$HOME_FILE" "$SITE_DIR/index.html"
fi

find "$SITE_DIR" -type f \( \
    -name "*.html" -o \
    -name "*.htm" -o \
    -name "*.css" -o \
    -name "*.js" \
\) | while read FILE
do
    rewrite_file "$FILE"
done

cat > "$SITE_DIR/.htaccess" <<'EOF'
Options -Indexes

DirectoryIndex index.html index.htm

<IfModule mod_rewrite.c>
RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.+)$ $1.html [L]

RewriteCond %{THE_REQUEST} /index\.html [NC]
RewriteRule ^index\.html$ / [R=301,L]
</IfModule>
EOF

phase_end

phase_start "Inventaire"

HTML_COUNT=$(count_files '\.(html|htm)$')
IMAGE_COUNT=$(count_files '\.(jpg|jpeg|png|gif|webp|svg|ico)$')
PDF_COUNT=$(count_files '\.pdf$')
CSS_COUNT=$(count_files '\.css$')
JS_COUNT=$(count_files '\.js$')
FONT_COUNT=$(count_files '\.(woff|woff2|ttf|otf|eot)$')
DOC_COUNT=$(count_files '\.(doc|docx|xls|xlsx|ppt|pptx|odt|ods|odp)$')
VIDEO_COUNT=$(count_files '\.(mp4|webm|mov|avi)$')
AUDIO_COUNT=$(count_files '\.(mp3|wav|ogg)$')
TOTAL_COUNT=$(find "$SITE_DIR" -type f | wc -l)

FAILED_COUNT=$(grep -Ei "ERROR 404|404 Not Found|ERROR 403|403 Forbidden|failed|unable to resolve|Connection refused|No such file" "$LOG_FILE" | wc -l)

grep -Ei "ERROR 404|404 Not Found|ERROR 403|403 Forbidden|failed|unable to resolve|Connection refused|No such file" "$LOG_FILE" > "$BROKEN_LIST" || true
grep -R "web.archive.org" "$SITE_DIR" > "$WAYBACK_LIST" || true
grep -R "$TARGET_DOMAIN.*\.babylon-project\.fr" "$SITE_DIR" > "$DUPLICATE_DOMAIN_LIST" || true
grep -R "/acces-data/$SOURCE_DOMAIN/\(raw\|clean\|site\)" "$SITE_DIR" > "$INTERNAL_PATH_LIST" || true

WAYBACK_LEFT=$(cat "$WAYBACK_LIST" | wc -l)
DUPLICATE_DOMAIN_LEFT=$(cat "$DUPLICATE_DOMAIN_LIST" | wc -l)
INTERNAL_PATH_LEFT=$(cat "$INTERNAL_PATH_LIST" | wc -l)

phase_end

if [ -n "$DEPLOY_DIR" ]; then
    phase_start "Publication"

    mkdir -p "$DEPLOY_DIR"

    if [ -d "$DEPLOY_DIR" ]; then
        find "$DEPLOY_DIR" -mindepth 1 -maxdepth 1 -exec rm -rf {} +
        cp -a "$SITE_DIR/." "$DEPLOY_DIR/"
    fi

    phase_end
fi

phase_start "Rapport"

END_GLOBAL=$(date +%s)
TOTAL_DURATION=$((END_GLOBAL - START_GLOBAL))
TOTAL_COST=$(awk "BEGIN { printf \"%.2f\", ($TOTAL_DURATION / 3600) * $HOURLY_RATE }")

{
    echo "Rapport BBL-Archive-Clone"
    echo "========================="
    echo ""
    echo "Version       : $VERSION"
    echo "Source archive: $ARCHIVE_URL"
    echo "Domaine source: $SOURCE_DOMAIN"
    echo "Date archive  : $ARCHIVE_DATE"
    echo "URL cible     : $TARGET_URL"
    echo "Base path     : $BASE_PATH"
    echo "URL publique  : $PUBLIC_URL"
    echo ""
    echo "Dossier brut     : $RAW_DIR"
    echo "Dossier nettoyé  : $CLEAN_DIR"
    echo "Dossier publiable: $SITE_DIR"

    if [ -n "$DEPLOY_DIR" ]; then
        echo "Dossier publié   : $DEPLOY_DIR"
    fi

    echo ""
    echo "Tarif horaire : $HOURLY_RATE €/h"
    echo "Durée totale  : ${TOTAL_DURATION}s"
    echo "Coût total    : ${TOTAL_COST} €"
    echo ""
    echo "Phases"
    echo "------"

    for i in "${!PHASE_NAMES[@]}"
    do
        echo "${PHASE_NAMES[$i]} : ${PHASE_DURATIONS[$i]}s / ${PHASE_COSTS[$i]} €"
    done

    echo ""
    echo "Fichiers récupérés"
    echo "------------------"
    echo "Pages HTML : $HTML_COUNT"
    echo "Images     : $IMAGE_COUNT"
    echo "PDF        : $PDF_COUNT"
    echo "CSS        : $CSS_COUNT"
    echo "JavaScript : $JS_COUNT"
    echo "Polices    : $FONT_COUNT"
    echo "Documents  : $DOC_COUNT"
    echo "Vidéos     : $VIDEO_COUNT"
    echo "Audios     : $AUDIO_COUNT"
    echo "Total      : $TOTAL_COUNT"
    echo ""
    echo "Ressources non récupérées"
    echo "-------------------------"
    echo "Erreurs détectées : $FAILED_COUNT"
    echo "Détail            : $BROKEN_LIST"
    echo ""
    echo "Contrôle qualité"
    echo "----------------"
    echo "Occurrences restantes web.archive.org : $WAYBACK_LEFT"
    echo "Domaines cibles dupliqués             : $DUPLICATE_DOMAIN_LEFT"
    echo "Chemins internes restants             : $INTERNAL_PATH_LEFT"
    echo ""
    echo "Détail Wayback        : $WAYBACK_LIST"
    echo "Détail domaines       : $DUPLICATE_DOMAIN_LIST"
    echo "Détail chemins internes: $INTERNAL_PATH_LIST"
    echo ""
    echo "Fin du rapport."
} > "$REPORT_FILE"

{
    echo "phase;duree_secondes;cout_euros"

    for i in "${!PHASE_NAMES[@]}"
    do
        echo "${PHASE_NAMES[$i]};${PHASE_DURATIONS[$i]};${PHASE_COSTS[$i]}"
    done

    echo ""
    echo "type;nombre"
    echo "html;$HTML_COUNT"
    echo "images;$IMAGE_COUNT"
    echo "pdf;$PDF_COUNT"
    echo "css;$CSS_COUNT"
    echo "js;$JS_COUNT"
    echo "polices;$FONT_COUNT"
    echo "documents;$DOC_COUNT"
    echo "videos;$VIDEO_COUNT"
    echo "audios;$AUDIO_COUNT"
    echo "total;$TOTAL_COUNT"
    echo "non_recupere;$FAILED_COUNT"
    echo "wayback_restants;$WAYBACK_LEFT"
    echo "domaines_dupliques;$DUPLICATE_DOMAIN_LEFT"
    echo "chemins_internes;$INTERNAL_PATH_LEFT"
} > "$CSV_FILE"

phase_end

echo ""
echo "======================================"
echo "BBL-Archive-Clone terminé"
echo "======================================"
echo "Version             : $VERSION"
echo "Domaine source      : $SOURCE_DOMAIN"
echo "URL cible           : $TARGET_URL"
echo "Base path           : $BASE_PATH"
echo "URL publique        : $PUBLIC_URL"
echo "Site restauré       : $SITE_DIR"
echo "Rapport             : $REPORT_FILE"
echo "CSV                 : $CSV_FILE"

if [ -n "$DEPLOY_DIR" ]; then
    echo "Publié dans         : $DEPLOY_DIR"
else
    echo "Publication         : non effectuée"
fi

echo "Wayback restants    : $WAYBACK_LEFT"
echo "Domaines dupliqués  : $DUPLICATE_DOMAIN_LEFT"
echo "Chemins internes    : $INTERNAL_PATH_LEFT"
echo "Coût estimé         : $TOTAL_COST €"
echo "======================================"