<?php

require '.php/pdf.php';

if ($_SERVER['REQUEST_METHOD'] !== 'GET' && $_SERVER['REQUEST_METHOD'] !== 'POST' && $_SERVER['REQUEST_METHOD'] !== 'HEAD') {
    header('Status: 405');
    header('Content-Length: 0');
    header('Allow: GET, POST, HEAD');
    exit;
}

$info = $_SERVER['PATH_INFO'];
if ($info !== '') {
    header('Status: 404');
    header('Content-Length: 0');
    exit;
}

$url = isset($_GET['url']) ? str_replace(' ', '+', $_GET['url']) : null;
$format = $_GET['format'] ?? 'json';

function jenc($data): string {
    return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
}

$file = tmpfile();
$headerfile = tmpfile();
if (!$file || !$headerfile) {
    header('Status: 500');
    header('Content-Length: 0');
    exit;
}
$cacheFile = null;
$tmpfilename = stream_get_meta_data($file)['uri'];
$filename = $tmpfilename;
$headerfilename = stream_get_meta_data($headerfile)['uri'];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $stdin = fopen("php://input", "rb");
    while (!feof($stdin)) {
        if (($data = fread($stdin, 8192)) === false)
            break;
        fwrite($file, $data);
    }
    fclose($stdin);
} else {
    if ($cache = fopen('certificates/.cache.csv', 'r')) {
        while (($line = fgets($cache)) !== false) {
            $parts = explode(';', trim($line), 3);
            $timestamp = intval($parts[0]);
            if ($parts[2] !== $url) continue;
            $cacheFile = 'certificates/' . $parts[1] . '.pdf';
            break;
        }
        fclose($cache);
    }

    if ($cacheFile !== null) {
        $filename = $cacheFile;
    } else {
        if (exec("curl -sk -D " . escapeshellarg($headerfilename) . " -o " . escapeshellarg($filename) . "  " . escapeshellarg($url)) === false) {
            header('Status: 500');
            header('Content-Length: 0');
            exit;
        }
    }
}

$timestamp = time();

if ($format === 'text') {
    header('Content-Type: text/plain; charset=UTF-8');
    passthru("pdftotext -raw " . escapeshellarg($filename) . " -");
} else if ($format === 'sig') {
    header('Content-Type: text/plain; charset=UTF-8');
    passthru("pdfsig " . escapeshellarg($filename));
} else if ($format === 'json') {
    header('Content-Type: application/json; charset=UTF-8');

    if (($cert = parse_pdf($filename, true)) === null) {
        header('Status: 500');
        header('Content-Length: 0');
        exit;
    }
    $certType = $cert['type'];
    $certId = $cert['id'];

    if ($certType === 'traces') {
        if ($certId !== null && $url !== null && $cacheFile === null) {
            copy($filename, "certificates/$certId.pdf");
            file_put_contents('certificates/.cache.csv', "$timestamp;$certId;$url\n", FILE_APPEND);
        }
    } else if ($certType !== 'unknown') {
        if ($certId !== null && $url !== null && $cacheFile === null) {
            copy($filename, "certificates/$certId.appendix.pdf");
            file_put_contents('certificates/.cache.csv', "$timestamp;$certId.appendix;$url\n", FILE_APPEND);
        }
    }

    echo jenc($cert);
    exit;
} else if ($cacheFile === $filename) {
    header('Content-Type: application/pdf');
    header('Content-Length: ' . filesize($filename));
    header('Content-Disposition: inline; filename="' . basename($filename) . '"');
    readfile($filename);
} else {
    $headers = [];
    $status_code = null;
    foreach (explode("\n", file_get_contents($headerfilename)) as $line) {
        if (trim($line) === '') break;
        if ($status_code === null) {
            $status_code = intval(explode(' ', $line)[1]);
            if ($status_code !== 200)
                break;
            continue;
        }
        [$k,$v] = explode(':', $line, 2);
        $k = strtolower(trim($k));
        $v = trim($v);
        $headers[$k] = $v;
    }

    if (str_starts_with($headers['content-type'], "application/pdf")) {
        header('Content-Type: application/pdf');
        $content_length = null;
        if (isset($headers['content-length'])) {
            $content_length = intval($headers['content-length']);
            header('Content-Length: ' . $headers['content-length']);
        }
        $parts = explode('/', $url);
        $realFilename = $parts[sizeof($parts) - 1];
        if (isset($headers['content-disposition'])) {
            preg_match('@filename="(.*?)"@', $headers['content-disposition'], $matches);
            $realFilename = $matches[1];
        }
        header('Content-Disposition: inline; filename="' . $realFilename . '"');
        fpassthru($file);
    } else {
        header('Status: 500');
        header('Content-Length: 0');
    }
}
