<?php
// box.php: list a template's inputs, measure it and export it as a PDF with the PiQ SaaS API.
// PHP 8.0 or later, with the curl extension.

$key = getenv('PIQ_API_KEY');
$base = rtrim(getenv('PIQ_URL') ?: 'https://saas.parametriq.co.uk', '/');
$storage = getenv('PIQ_STORAGE'); // optional: a registered storage's name
if (!$key) {
    fwrite(STDERR, "Set PIQ_API_KEY to your API key.\n");
    exit(1);
}

const TEMPLATE = "L=400,\"Length\"\nW=300,\"Width\"\nP1=[L,0]\nP2=[L,W]\nP3=[0,W]\nPOLYLINE @1,[P0,P1,P2,P3],TRUE,0";
// the template itself, or (optional) where it is kept in your storage
$template = $storage ? ['source' => ['storage' => $storage, 'key' => 'templates/box.piq']] : ['template' => TEMPLATE];
$values = ['L' => 500, 'W' => 250];

/** Posts the body as JSON; returns the response body and headers, or stops with the problem. */
function post(string $path, array $body): array
{
    global $key, $base;
    $headers = [];
    $curl = curl_init($base . $path);
    curl_setopt_array($curl, [
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => json_encode($body),
        CURLOPT_HTTPHEADER => ["X-API-KEY: $key", 'Content-Type: application/json'],
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HEADERFUNCTION => function ($curl, $line) use (&$headers) {
            if (str_contains($line, ':')) {
                [$name, $value] = explode(':', $line, 2);
                $headers[strtolower(trim($name))] = trim($value);
            }
            return strlen($line);
        },
    ]);
    $response = curl_exec($curl);
    $status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
    if ($response === false) {
        fwrite(STDERR, curl_error($curl) . "\n");
        exit(1);
    }
    if ($status >= 300) {
        fwrite(STDERR, "Error $status\n");
        $problem = json_decode($response, true); // a 401 has no body
        if (!is_array($problem)) $problem = ['detail' => $response];
        foreach (['title', 'detail'] as $part)
            if (!empty($problem[$part])) fwrite(STDERR, $problem[$part] . "\n");
        foreach ($problem['errors'] ?? [] as $field => $messages)
            fwrite(STDERR, "  $field: " . implode(' ', $messages) . "\n");
        exit(1);
    }
    return [$response, $headers];
}

// 1. The template's labelled variables
[$json] = post('/inputs', $template);
foreach (json_decode($json, true)['inputs'] as $i)
    echo "{$i['name']}: {$i['label']} ({$i['kind']}, " . json_encode($i['value']) . ")\n";

// 2. The drawing measured, with the values given
[$json] = post('/measure', $template + ['values' => $values]);
$m = json_decode($json, true);
$cut = 0;
foreach ($m['layers'] as $layer)
    if ($layer['layer'] === 'Cut') $cut = $layer['length'];
echo "Size: {$m['width']} x {$m['height']}, cut length: $cut\n";

// 3. The drawing as a PDF
[$pdf, $headers] = post('/export/pdf', $template + ['values' => $values]);
file_put_contents('box.pdf', $pdf);
echo "Saved box.pdf ({$headers['x-piq-warnings']} warnings)\n";

// 4. Optional: the PDF saved to your storage instead of downloaded
if ($storage) {
    $destination = ['storage' => $storage, 'key' => 'drawings/box.pdf'];
    [$json] = post('/save/pdf', $template + ['values' => $values, 'destination' => $destination, 'overwrite' => true]);
    $saved = json_decode($json, true);
    echo "Saved {$saved['key']} to {$saved['storage']} ({$saved['size']} bytes)\n";
}
