# box.py: list a template's inputs, measure it and export it as a PDF with the PiQ SaaS API.
# Python 3.8 or later, with requests (pip install requests).
import os
import sys

import requests

key = os.environ.get("PIQ_API_KEY")
base = os.environ.get("PIQ_URL", "https://saas.parametriq.co.uk").rstrip("/")
storage = os.environ.get("PIQ_STORAGE")  # optional: a registered storage's name
if not key:
    sys.exit("Set PIQ_API_KEY to your API key.")

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 = {"source": {"storage": storage, "key": "templates/box.piq"}} if storage else {"template": TEMPLATE}
values = {"L": 500, "W": 250}

session = requests.Session()
session.headers["X-API-KEY"] = key


def post(path, body):
    response = session.post(base + path, json=body, timeout=60)
    if not response.ok:
        fail(response)
    return response


def fail(response):
    print(f"Error {response.status_code} {response.reason}", file=sys.stderr)
    if response.content:  # a 401 has no body
        try:
            problem = response.json()
        except ValueError:
            problem = {"detail": response.text}
        for part in ("title", "detail"):
            if problem.get(part):
                print(problem[part], file=sys.stderr)
        for field, messages in (problem.get("errors") or {}).items():
            print(f"  {field}: {' '.join(messages)}", file=sys.stderr)
    sys.exit(1)


# 1. The template's labelled variables
for i in post("/inputs", template).json()["inputs"]:
    print(f"{i['name']}: {i['label']} ({i['kind']}, {i['value']})")

# 2. The drawing measured, with the values given
m = post("/measure", {**template, "values": values}).json()
cut = next((layer["length"] for layer in m["layers"] if layer["layer"] == "Cut"), 0)
print(f"Size: {m['width']} x {m['height']}, cut length: {cut}")

# 3. The drawing as a PDF
pdf = post("/export/pdf", {**template, "values": values})
with open("box.pdf", "wb") as file:
    file.write(pdf.content)
print(f"Saved box.pdf ({pdf.headers.get('X-PiQ-Warnings')} warnings)")

# 4. Optional: the PDF saved to your storage instead of downloaded
if storage:
    destination = {"storage": storage, "key": "drawings/box.pdf"}
    body = {**template, "values": values, "destination": destination, "overwrite": True}
    saved = post("/save/pdf", body).json()
    print(f"Saved {saved['key']} to {saved['storage']} ({saved['size']} bytes)")
