#!/usr/bin/env php
<?php

$options = getopt("", [
    "from:",
    "to:",
    "bytes:",
    "e3g-progress",
    "help",
]);


if (isset($options["help"])) {
    echo <<<HELP
Usage: php progress [options] 

Options:
  --bytes=length        total length in bytes
  --from=%              initial value (default: 0)
  --to=%                final value (default: 100)
  --e3g-progress        Machine mode progress instead of human readable
  --help                Show this help and exit

HELP;
    exit(0);
}

$machine_readable_progress = isset($options["e3g-progress"]);
$from = isset($options["from"]) ? (int)$options["from"] : 0;
$to = isset($options["to"]) ? (int)$options["to"] : 100;
$totalBytes = isset($options["bytes"]) ? (int)$options["bytes"] : 0;
$progressFile = null; // not implemented in this version
if ($totalBytes < 1) $totalBytes = 1; // avoid division by zero

// --- function to print dynamic progress bar ---
function show_progress($count, $totalRows, $progressFile) 
{
    global $machine_readable_progress;
    global $last_percent;
    global $from, $to;

    $percent = (int)($totalRows > 0 ? ($count / $totalRows * 100)*($to-$from)/100+$from : 0);    
    if ($percent > 100) $percent = 100;
    if (isset($last_percent) && $percent == $last_percent) return; // avoid too frequent updates
    $last_percent = $percent;
    if ($machine_readable_progress)
    {
        $msg=sprintf("Progress: %d%%\n", $percent);
        fwrite(STDERR,  $msg);
        fflush(STDERR);
        if ($progressFile) file_put_contents($progressFile, $msg);
        return;
    }
    // human readable progress bar
    $barLen = 40; // width of progress bar
    $filled = $totalRows > 0 ? (int)($barLen * $percent / 100) : 0;
    $bar = str_repeat("#", $filled) . str_repeat("-", $barLen - $filled);
    $text = sprintf("[%s] %.0f%% (%d / %d bytes)                          ", $bar, $percent, $count, $totalRows);
    // write progress file
    if ($progressFile) file_put_contents($progressFile, sprintf("%d / %d bytes (%.2f%%)\n", $count, $totalRows, $percent));
    // write dynamic bar to stderr
    fwrite(STDERR, "\r" . $text);
    fflush(STDERR);
}

$currentBytes = 0;
while (!feof(STDIN)) {
    $data = fread(STDIN, 8192);
    if ($data === false) break;
    $currentBytes += strlen($data);
    echo $data;
    show_progress($currentBytes, $totalBytes, $progressFile);
}
show_progress($totalBytes, $totalBytes, $progressFile);
if ($to==100 && !$machine_readable_progress) fwrite(STDERR, "\n");