#!/bin/bash

# This isn't super efficient
# For a ~500 commit paper it takes about an hour on a 2019 laptop core.
# Assumptions:
#  - That checkouts for each commit will work (ok if build fails though)
#  - That your paper pdf name stays the same on all commits
#  - That you start on a 'clean' repo state, we need to be able to do checkouts!
# Requirements:
#   - You need imagemagick installed
#   - You need to make sure magick can handle PDFs, see https://stackoverflow.com/questions/52998331/imagemagick-security-policy-pdf-blocking-conversion
#   - You need FFMPEG installed
# Troubleshooting
#   - You should be seeing a nice clean updating status line and nothing else.
#   - Stop the script if not (you'll need to `kill` it)
#   - Look at whats in $papername-history/
# TODOs
#   - Add an embedded datestamp for every frame https://superuser.com/questions/649033/add-timestamp-to-image-from-linux-command-line
#   - Add colors/holds for specified git tags (e.g. submission, revision, CR)

# You need to set these two options!  You also need to make sure your
# working directory is clean; git reset --hard would be ideal.
papername="paper.pdf"
branchname="test"
# If this is empty string it'll use whatever makefile is around, otherwise will always replace with this one
goodmakefile=""


# Settings for frame creation, these are fine
imagequality=20
imagedensity=80
pagespercolumn=3
extratagframes=5

# working dirs
workdir=paperhistory-$papername
framedir=$workdir/paper-frames/
mkdir -p $framedir

# Rest of this is just the script
paper-to-png() {
    pagect=$(pdfinfo "$1" | awk '/^Pages:/ {print $2}')
    totalpage=$pagect
    tag=$3
    if [[ $pagect -lt $((pagespercolumn+1)) ]]; then
        magick  -density $imagedensity "$1" -quality $imagequality -background white -alpha remove -alpha off -append "$framedir/$2.png"
    else
        tctr=0
        cpage=0
        while [[ $pagect -gt $pagespercolumn ]]; do
            spage=$((cpage+pagespercolumn))
            magick -density $imagedensity "$1"[$cpage-$((spage-1))] -quality $imagequality -background white -alpha remove -alpha off -append "$framedir/tmp-$2-$tctr.png"
            cpage=$((cpage+pagespercolumn))
            pagect=$((pagect-pagespercolumn))
            ((tctr++))
        done
        magick -density $imagedensity "$1"[$cpage-$((totalpage-1))] -quality $imagequality -background white -alpha remove -alpha off -append "$framedir/tmp-$2-$tctr.png"
        ((tctr++))
        montage "$framedir/tmp-$2-[0-$((tctr-1))].png" -tile ${tctr}x1 -geometry +0+0 "$framedir/$2.png"
        rm $framedir/tmp-*.png
    fi
    if [[ $tag != "" ]]; then
        # We have a tag, hold here for a specified delay
        echo "Generating special frames for git tag $tag"
        magick "$framedir/$2.png" -font Roboto -fill red -pointsize 60 -gravity northwest -draw "text 0,0 '$tag'" "$framedir/$2.png"
        for i in $(seq 1 5); do
            cp "$framedir/$2.png" "$framedir/$2-$i.png"
        done
        #TODO then hold
    fi
}

ctr=0
skips=0

git checkout $branchname
git rev-list HEAD > $workdir/tmp_revs
totalrevs=$(wc -l $workdir/tmp_revs | cut -f 1 -d ' ')
mkdir -p $framedir

echo -e "Making frames from the paper commits ...\n"

for rev in $(tac $workdir/tmp_revs); do
    rm *.pdf &> /dev/null
    rm $papername &> /dev/null
    git checkout "$rev" &> $workdir/logg
    # Sometimes things break and this can help.
    git restore . &> $workdir/logg
    if [[ -f Makefile ]]; then
        restore=1
    else
        restore=0
    fi

    if [[ $goodmakefile != "" ]]; then
        cp $goodmakefile Makefile
    fi
    make clean &> $workdir/logc
    timeout 15 make &> $workdir/log
    pctr=$(printf "%04i" "$ctr")
    tag=$(git describe --exact-match --tags 2> /dev/null)
    if [[ -e $papername ]]; then
        paper-to-png $papername "$pctr" $tag &> $workdir/logf
    else
        ((skips++))
    fi
    # status line update here
    echo -ne "\rCompleted: $ctr of $totalrevs (Skipped: $skips)"
    ((ctr++))
    make clean &> $workdir/logc
    if [[ $restore == 1 ]]; then
        git checkout Makefile &>> $workdir/logg
    else
        rm Makefile
    fi
done
echo -e "\nDone!"
echo "Making a video from the frames..."
totalframes=$(ls -1q $framedir | wc -l | tr -d '[:space:]')
rate=$(echo "scale=1 ; $totalframes / 60" | bc)

ffmpeg -v quiet -stats -framerate "$rate" -pattern_type glob -i "$framedir*.png" -c:v libx264 -pix_fmt yuv420p -vf "scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:-1:-1:white,tpad=stop_mode=clone:stop_duration=2" $workdir/${papername}-history.mp4

rm $workdir/tmp_revs

echo "See $workdir/${papername}-history.mp4 for the video and $framedir/ for the pngs"
