# box.rb: list a template's inputs, measure it and export it as a PDF with the PiQ SaaS API.
# Ruby 3.0 or later; net/http and json from the standard library.
require "json"
require "net/http"

KEY = ENV["PIQ_API_KEY"]
BASE = (ENV["PIQ_URL"] || "https://saas.parametriq.co.uk").chomp("/")
storage = ENV["PIQ_STORAGE"] # optional: a registered storage's name
abort "Set PIQ_API_KEY to your API key." if KEY.to_s.empty?

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 }

def post(path, body)
  uri = URI(BASE + path)
  response = Net::HTTP.post(uri, JSON.generate(body), "X-API-KEY" => KEY, "Content-Type" => "application/json")
  return response if response.is_a?(Net::HTTPSuccess)

  warn "Error #{response.code} #{response.message}"
  unless response.body.to_s.empty? # a 401 has no body
    problem = JSON.parse(response.body) rescue { "detail" => response.body }
    warn problem["title"] if problem["title"]
    warn problem["detail"] if problem["detail"]
    (problem["errors"] || {}).each { |field, messages| warn "  #{field}: #{messages.join(" ")}" }
  end
  exit 1
end

# 1. The template's labelled variables
JSON.parse(post("/inputs", template).body)["inputs"].each do |i|
  puts "#{i["name"]}: #{i["label"]} (#{i["kind"]}, #{i["value"]})"
end

# 2. The drawing measured, with the values given
m = JSON.parse(post("/measure", template.merge(values: values)).body)
cut = m["layers"].find { |layer| layer["layer"] == "Cut" }&.fetch("length") || 0
puts "Size: #{m["width"]} x #{m["height"]}, cut length: #{cut}"

# 3. The drawing as a PDF
pdf = post("/export/pdf", template.merge(values: values))
File.binwrite("box.pdf", pdf.body)
puts "Saved box.pdf (#{pdf["X-PiQ-Warnings"]} warnings)"

# 4. Optional: the PDF saved to your storage instead of downloaded
if storage
  destination = { storage: storage, key: "drawings/box.pdf" }
  saved = JSON.parse(post("/save/pdf", template.merge(values: values, destination: destination, overwrite: true)).body)
  puts "Saved #{saved["key"]} to #{saved["storage"]} (#{saved["size"]} bytes)"
end
