#!/usr/bin/env bash

# Optimizes everything the script can find in a folder,
# meaning it will compress files as much as possible,
# without losing any data (verification will be done
# in order to verify that no data has been done)
# (executable)

# TODO Run in parallel

dir=${1:-$PWD}
total=$(mktemp)
echo -n 0 > $total

function showtotal {
    echo "Total saved: $(cat "$total") bytes"
    rm $total
    exit
}

trap showtotal SIGTERM SIGINT SIGFPE

function replaceImg { # candidate original

    c="$1"
    o="$2"

    # File verifications
    if [ ! -f "$o" ]; then
        echo "→ Original is inexistant, skipping!"
        return
    fi
    if [ ! -f "$c" ]; then
        echo "→ Candidate is inexistant, skipping!"
        return
    fi

    # Size verifications
    cs=$(wc -c "$c" | cut -d' ' -f1)
    os=$(wc -c "$o" | cut -d' ' -f1)
    if [ $cs -le 0 ]; then
        echo "→ Candidate is empty, skipping!"
        rm "$c"
        return
    fi
    if [ $cs -eq $os ]; then
        echo "→ Candidate weight the same, skipping."
        rm "$c"
        return
    fi
    if [ $cs -gt $os ]; then
        echo "→ Candidate is larger, skipping."
        rm "$c"
        return
    fi

    # Bitmap verification
    ppmc="$(mktemp --suffix .ppm)"
    ppmo="$(mktemp --suffix .ppm)"
    convert "$c" "$ppmc"
    convert "$o" "$ppmo"

    if cmp --silent "$ppmo" "$ppmc"; then
        mv "$c" "$o"
        saved=$(($os - $cs))
        echo "→ $os ⇒ $cs (saved $saved bytes)"
        newtotal=$(($(cat $total) + $saved))
        echo -n $newtotal > $total
    else
        echo "→ Candidate don't have the same bit map as original, skipping!"
    fi
    rm "$ppmc" "$ppmo" "$c"

}

# JPEG (requires jpegtran)
while read image
do
    echo Processing $image

    prog=$(mktemp --suffix .jpg)
    jpegtran -copy all -progressive "$image" > "$prog"
    echo "→ Progressive done"

    optz=$(mktemp --suffix .jpg)
    jpegtran -copy all -optimize "$image" > "$optz"
    echo "→ Optimize done"

    progs=$(wc -c "$prog" | cut -d' ' -f1)
    optzs=$(wc -c "$optz" | cut -d' ' -f1)
    if [[ $progs -le $optzs ]]; then
        echo "→ Using progressive"
        replaceImg "$prog" "$image"
        rm "$optz"
    else
        echo "→ Using optimized"
        replaceImg "$optz" "$image"
        rm "$prog"
    fi

done <<< "$(find "$dir" -type f -iregex ".+.jpe?g$")"

# PNG (requires optipng)
while read image
do
    echo Processing $image

    temp=$(mktemp --suffix .png)
    cp "$image" "$temp"
    optipng -o7 -quiet "$temp"
    echo "→ Optimize done"

    replaceImg "$temp" "$image"

done <<< "$(find "$dir" -type f -iname "*.png")"

# SVG (requires svgo)
while read image
do
    echo Processing $image

    temp=$(mktemp --suffix .svg)
    cp "$image" "$temp"
    svgo --quiet --config $HOME/.config/optiSvgo.yml "$temp"
    echo "→ Optimize done"

    replaceImg "$temp" "$image"

done <<< "$(find "$dir" -type f -iname "*.svg")"

# GIT (requires git)
find "$dir" -type d -name .git -print0 | while IFS= read -r -d '' dir; do
    (cd "$dir"; git gc)
done

showtotal