<?php
require ".php/format.inc";
require ".php/auth.inc";
include ".php/devices.inc";

authenticate(['stat']);

$fileNames = array_filter(scandir('files/'), function($e) { return str_starts_with($e, 'Elwig-'); });
usort($fileNames, 'version_compare');
$latestVersion = sizeof($fileNames) > 0 ? substr(substr($fileNames[sizeof($fileNames) - 1], 6), 0, -4) : null;

$osVersions = [
    'Microsoft Windows NT 10.0.10240.0' => 'Windows 10 (1507)',
    'Microsoft Windows NT 10.0.10586.0' => 'Windows 10 (1511)',
    'Microsoft Windows NT 10.0.14393.0' => 'Windows 10 (1607)',
    'Microsoft Windows NT 10.0.15063.0' => 'Windows 10 (1703)',
    'Microsoft Windows NT 10.0.16299.0' => 'Windows 10 (1709)',
    'Microsoft Windows NT 10.0.17134.0' => 'Windows 10 (1803)',
    'Microsoft Windows NT 10.0.17763.0' => 'Windows 10 (1809)',
    'Microsoft Windows NT 10.0.18362.0' => 'Windows 10 (1903)',
    'Microsoft Windows NT 10.0.18363.0' => 'Windows 10 (1909)',
    'Microsoft Windows NT 10.0.19041.0' => 'Windows 10 (2004)',
    'Microsoft Windows NT 10.0.19042.0' => 'Windows 10 (20H2)',
    'Microsoft Windows NT 10.0.19043.0' => 'Windows 10 (21H1)',
    'Microsoft Windows NT 10.0.19044.0' => 'Windows 10 (21H2)',
    'Microsoft Windows NT 10.0.19045.0' => 'Windows 10 (22H2)',
    'Microsoft Windows NT 10.0.22000.0' => 'Windows 11 (21H2)',
    'Microsoft Windows NT 10.0.22621.0' => 'Windows 11 (22H2)',
    'Microsoft Windows NT 10.0.22631.0' => 'Windows 11 (23H2)',
    'Microsoft Windows NT 10.0.26100.0' => 'Windows 11 (24H2)',
    'Microsoft Windows NT 10.0.26200.0' => 'Windows 11 (25H2)',
];

$latestOsVersions = [];
foreach ($osVersions as $id => $name) {
    $latestOsVersions[substr($name, 0, 10)] = $name;
}

$DEVICES ??= [];

if ($_SERVER['PATH_INFO'] === '/log') {
    header("Content-Type: text/html; charset=UTF-8");
    echo "<!DOCTYPE html><html lang='en'><head><title>Table - Activity Statistics - Elwig</title><style>table{border-collapse:collapse;}th,td{border:1px solid black;padding:0.25em 0.5em;}</style></head><body><table>\n";
    echo "<tr><th>Timestamp</th><th>IP Address</th><th>Method</th><th>URI</th><th>Format</th><th>User Agent</th></tr>\n";
    if ($_SERVER['QUERY_STRING'] === 'full') {
        passthru(<<<EOF
cat files/.log.csv \
| awk -F'|' -vOFS='|' '{\$1 = strftime("%F %T", $1); print $0}' \
| sed 's:|:</td><td>:g;s:^:<tr><td>:g;s:$:</td></tr>:g'
EOF);
    } else {
        passthru(<<<EOF
cat files/.log.csv | grep -E '\|json\|$|\|Elwig/' | grep -v "WGX|PICARD|ENTERPRISE|GEORGIOU|78A16E85-410A-4" \
| awk -F'|' -vOFS='|' '{\$1 = strftime("%F %T", $1); print $0}' \
| sed 's:|:</td><td>:g;s:^:<tr><td>:g;s:$:</td></tr>:g'
EOF);
    }
    echo "</table></body></html>\n";
    exit;
} else if ($_SERVER['PATH_INFO'] === '') {
    $format = get_fmt();
    $stat = [];
    if (($file = fopen('files/.log.csv', 'r'))) {
        while (($line = fgets($file)) !== false) {
            $line = explode('|', $line);
            if (sizeof($line) < 6) continue;
            if (!str_starts_with($line[5], 'Elwig/')) continue;
            if (str_contains($line[5], "WGX") || str_contains($line[5], "PICARD") || str_contains($line[5], "ENTERPRISE") || str_contains($line[5], "GEORGIOU") || str_contains($line[5], "78A16E85-410A-4")) continue;
            $timestamp = intval($line[0]);
            $version = substr(explode(' ', $line[5], 2)[0], 6);
            $comment = preg_match("/\((.*?), *(.*?), *(.*?), *(.*?)\)/", $line[5], $m);
            $token = $m[1];
            $branch = $m[2];
            $device = $m[3];
            $win = $m[4];
            if (!isset($stat[$token])) $stat[$token] = [];
            if (!isset($stat[$token][$device])) $stat[$token][$device] = [];
            $addr = $line[1];
            if (str_contains($addr, ':')) {
                $list = explode(':', $addr);
                $addr = implode(':', array_splice($list, 0, 4)) . '::';
            }
            $stat[$token][$device][$timestamp] = [$version, $branch, $win, $addr];
        }
        fclose($file);
    }

    if ($format === 'json') {
        header('Content-Type: application/json; charset=UTF-8');
        echo "{\"clients\":[\n";
        $first1 = true;
        foreach ($stat as $token => $devices) {
            if (!$first1) echo ",\n";
            echo "  {\"token\": \"$token\", \"devices\": [\n";
            $first2 = true;
            foreach ($devices as $device => $data) {
                if (!$first2) echo ",\n";
                echo "    {";
                $timestamp = array_key_last($data);
                $ref = $timestamp;
                foreach (array_reverse(array_keys($data)) as $t) {
                    if ($t + 90 * 60 > $ref) {
                        $ref = $t;
                    } else {
                        break;
                    }
                }
                $addr = array_reverse(array_unique(array_map(function ($d) {
                    return "\"$d[3]\"";
                }, array_values($data))));
                $d = $data[$timestamp];
                $name = $DEVICES[$token][$device] ?? $device;
                $active = $timestamp + 90 * 60 > time();
                $activeStr = $active ? 'true' : 'false';
                $from = date('c', $ref);
                $to = date('c', $timestamp);
                $hours = intval((($active ? time() : $timestamp) - $ref) / 60 / 60 + 0.4);
                $win = isset($osVersions[$d[2]]) ? '"' . $osVersions[$d[2]] . '"' : "null";
                echo "\"branch\": \"$d[1]\", \"description\": \"$name\", \"name\": \"$device\", \"isActive\": $activeStr, " .
                    "\"lastActivity\": {\"start\": \"$from\", \"end\": \"$to\", \"hours\": $hours}, " .
                    "\"elwigVersion\": \"$d[0]\", \"osVersion\": $win, \"osVersionFull\": \"$d[2]\", " .
                    "\"addresses\": [" . implode(",", $addr) . "]";
                echo "}";
                $first2 = false;
            }
            echo "\n  ]}";
            $first1 = false;
        }
        echo "\n]}\n";
    } else if ($format === 'text') {
        header('Content-Type: text/plain; charset=UTF-8');
        echo "Client  Branch            Device                Device Name           Last Activity                 Elwig Version  OS Version                         IP Addresses\n";
        foreach ($stat as $token => $devices) {
            foreach ($devices as $device => $data) {
                echo "$token     ";
                $timestamp = array_key_last($data);
                $ref = $timestamp;
                foreach (array_reverse(array_keys($data)) as $t) {
                    if ($t + 90 * 60 > $ref) {
                        $ref = $t;
                    } else {
                        break;
                    }
                }
                $addr = array_reverse(array_unique(array_map(function ($d) {
                    return $d[3];
                }, array_values($data))));
                $d = $data[$timestamp];
                $name = $DEVICES[$token][$device] ?? $device;
                echo mb_str_pad($d[1], 16) . "  " . mb_str_pad($name, 20) . "  " . mb_str_pad($device, 20) . "  ";
                if ($timestamp + 90 * 60 > time()) {
                    echo mb_str_pad(date('d.m.Y, H:i', $timestamp) . " (since " . intval((time() - $ref) / 60 / 60 + 0.4) . "h)", 28);
                } else {
                    echo mb_str_pad(date('d.m.Y, H:i', $timestamp) . " (for " . intval(($timestamp - $ref) / 60 / 60 + 0.4) . "h)", 28);
                }
                echo "  " . mb_str_pad($d[0], 13) . "  ";
                if (isset($osVersions[$d[2]])) {
                    echo mb_str_pad($osVersions[$d[2]], 33) . "  ";
                } else {
                    echo mb_str_pad($d[2], 33) . "  ";
                }
                echo implode(", ", array_slice($addr, 0, 5));
                echo "\n";
            }
        }
    } else if ($format === 'table') {
        header('Content-Type: text/html; charset=UTF-8');
        echo "<!DOCTYPE html>\n<html lang='en'>\n";
        echo "<head><title>Activity Statistics - Elwig</title><style>table{border-collapse:collapse;}th,td{border:1px solid black;padding:0.25em 0.5em;}</style></head>\n";
        echo "<body>\n";
        echo "<h1>Activity Statistics</h1>\n";
        echo "<table>\n";
        echo "<tr><th>Client</th><th>Branch</th><th>Device</th><th>Device Name</th><th>Last Activity</th><th>Elwig Version</th><th>OS Version</th><th>IP Addresses</th></tr>\n";
        foreach ($stat as $token => $devices) {
            $first = true;
            foreach ($devices as $device => $data) {
                echo "<tr>";
                if ($first) {
                    $n = sizeof($devices);
                    echo "<td rowspan='$n'>$token</td>";
                    $first = false;
                }
                $timestamp = array_key_last($data);
                $ref = $timestamp;
                foreach (array_reverse(array_keys($data)) as $t) {
                    if ($t + 90 * 60 > $ref) {
                        $ref = $t;
                    } else {
                        break;
                    }
                }
                $addr = array_reverse(array_unique(array_map(function ($d) {
                    return $d[3];
                }, array_values($data))));
                $d = $data[$timestamp];
                $name = $DEVICES[$token][$device] ?? $device;
                echo "<td>$d[1]</td>";
                if ($timestamp + 90 * 60 > time()) {
                    echo "<td><b>$name</b></td>";
                    echo "<td><b>$device</b></td>";
                    echo "<td style='color:darkgreen'>" . date('d.m.Y, H:i', $timestamp) . " (since " . intval((time() - $ref) / 60 / 60 + 0.4) . "h)</td>";
                } else {
                    echo "<td>$name</td>";
                    echo "<td>$device</td>";
                    echo "<td>" . date('d.m.Y, H:i', $timestamp) . " (for " . intval(($timestamp - $ref) / 60 / 60 + 0.4) . "h)</td>";
                }
                echo "<td>$d[0]</td>";
                if (isset($osVersions[$d[2]])) {
                    echo "<td>" . $osVersions[$d[2]] . "</td>";
                } else {
                    echo "<td>$d[2]</td>";
                }
                echo "<td>" . implode("<br>", array_slice($addr, 0, 5)) . "</td>";
                echo "</tr>\n";
            }
        }
        echo "</table>\n";
        echo "<p><a href='stat/log'>Log</a> <a href='stat/log?full'>Full Log</a></p>\n";
        echo "</body>\n</html>\n";
    } else {
        header('Content-Type: text/html; charset=UTF-8');
?>
<!DOCTYPE html>
<html lang="de">
<head>
  <meta charset="UTF-8"/>
  <title>Statistiken - Elwig</title>
  <link rel="icon" href="/favicon.ico" sizes="16x16 20x20 24x24 30x30 32x32 36x36 40x40 48x48 60x60 64x64 72x72 80x80 96x96 128x128 256x256"/>
  <link rel="stylesheet" href="/res/stat.css"/>
  <meta name="viewport" content="width=device-width,initial-scale=1.0"/>
  <meta name="theme-color" content="#A040C0"/>
  <meta name="mobile-web-app-capable" content="yes"/>
  <meta name="apple-mobile-web-app-capable" content="yes"/>
  <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>
</head>
<body>
<?php
        foreach ($stat as $token => $devices) {
            echo "<div class='client'><span>$token</span><div>\n";
            foreach ($devices as $device => $data) {
                $timestamp = array_key_last($data);
                $addr = array_reverse(array_unique(array_map(function ($d) {
                    return $d[3];
                }, array_values($data))));
                $d = $data[$timestamp];
                $name = $DEVICES[$token][$device] ?? $device;
                $active = $timestamp + 36 * 60 * 60 > time() ? 'online' : ($timestamp + 28 * 24 * 60 * 60 > time() ? 'offline' : 'inactive');
                echo "<div class='device $active'>";

                echo "<div class='versions'>";
                $elwigVers = $latestVersion === null ? '' : ($d[0] === $latestVersion ? 'latest' : 'deprecated');
                echo "<span class='elwig $elwigVers'><img src='/favicon.ico' width='16' height='16'/> $d[0]</span>";
                if (isset($osVersions[$d[2]])) {
                    $v = $osVersions[$d[2]];
                    $l = $latestOsVersions[substr($v, 0, 10)] ?? null;
                    $osVers = $l === null ? '' : ($l === $v ? 'latest' : 'deprecated');
                    echo "<span class='os $osVers'>" . str_replace('Windows', "<img src='/res/windows.png' width='16' height='16'/> ", $v) . "</span>";
                } else {
                    echo "<span class='os'>$d[2]</span>";
                }
                echo "</div>";

                echo "<div class='date'>" . date('d.m.Y', $timestamp) . "</div>";
                echo "<div class='name'>$name</div>";
                echo "<div class='id'>$device</div>";
                echo "<div class='address'>" . implode("<br>", array_slice($addr, 0, 1)) . "</div>";
                echo "</div>\n";
            }
            echo "</div></div>\n";
        }
    }
    echo "</body>\n</html>\n";
} else {
    header('Status: 404');
    header('Content-Length: 0');
    exit();
}
