#!/bin/bash

set -euo pipefail

help_message="$(cat <<END
usage: $(basename "$0") [OPTIONS...] INPUT_PDF OUTPUT_PDF

Converts a PDF file to a series of JPEG images using convert to reduce the quality 
and then merges back the result in a single pdf 

Options:
    -q, --quality    Set the JPEG quality (default: 75)
    -v, --verbose    Enable verbose output, also shows an estimate of remaining time
    -h, --help       Display this help message

END
)"

function show_usage() {
    echo "$help_message"
    exit 1
}

quality=75
verbose=false

while [[ $# -gt 0 ]]
do
    key="$1"

    case $key in
        -q|--quality)
            quality="$2"
            shift # past argument
            shift # past value
            ;;
        -v|--verbose)
            verbose=true
            shift # past argument
            ;;
        -h|--help)
            show_usage
            ;;
        -*)
            echo "Unknown option: $key"
            show_usage
            ;;
        *)
            break
            ;;
    esac
done

if [ -z "$1" ] || [ -z "$2" ]; then
    show_usage
fi

input_file="$1"
output_file="$2"

temp_pages_dir="$(mktemp -d)"

function logf {
    if [ "$verbose" = true ]; then
        printf "$@"
    fi
}

logf "Converting \"$input_file\" to \"$output_file\"\n"

page_count=$(pdfinfo "$input_file" | grep Pages | awk '{print $2}')

logf "Processing $page_count pages\n"

start=$(date +%s.%N)
for i in $(seq 0 $((page_count-1))); do
    iter_start=$(date +%s.%N)

    # convert -density 300 -quality "$quality" "${input_file}[$i]" "$temp_pages_dir/$i.jpg"
    
    # Equivalent "gs" command that avoids convert's security policies  
    gs -sDEVICE=jpeg -o "$temp_pages_dir/$i.jpg" -dFirstPage="$i" -dLastPage="$i" -dJPEGQ="$quality" -r300x300 "$input_file"

    # Compute estimated remaining time
    end=$(date +%s.%N)
    elapsed=$(echo "$end - $start" | bc)
    iter_elapsed=$(echo "$end - $iter_start" | bc)
    remaining=$(echo "($elapsed / ($i + 1)) * ($page_count - $i)" | bc)
    remaining_fmt=$(printf "%02d:%02d:%02d" $((remaining/3600)) $((remaining/60)) $((remaining%60)))

    logf "Compressed page $((i+1)) in $(printf '%.2f' "$iter_elapsed")s (estimated remaining time $remaining_fmt)\n"
done

logf "Merging compressed pages to a single PDF\n"
convert "$temp_pages_dir"/*.jpg "$output_file"

rm -r "$temp_pages_dir"

logf "Done\n"
