// Package provision implements the slice-8A provisioning BACK HALF: after the slice-7 bring-up
// front half (restore → identity → size → start), the agent mints a per-guest local-API token,
// renders the stable bootstrap.json contract, and populates a read-only config mount the golden's
// baked controller-bootstrap unit consumes (F3: host-side only, no pct exec).
//
// The agent NEVER enters the guest and NEVER puts a registry credential in the guest (the
// controller image is baked into the golden — configs/build-golden.sh). The only secret written
// into the guest is the per-guest local-API token, in the 0600 bootstrap.json on the config mount.
package provision

import "encoding/json"

// SchemaV2 is the stable agent→controller contract version. It MUST stay byte-compatible with the
// controller's internal/bootstrap.SchemaV2 / Bootstrap shape (cross-repo contract; doc_test.go
// pins the key set, mirroring the controller's bootstrap_test.go). v2 changed the contract's
// MEANING — the controller now PULLS its full controller.yaml from the hub using a per-customer
// retrieval passphrase (which yields the CUSTOMER-scoped hub key), instead of the agent baking its
// HOST key. So the agent no longer puts the hub api_key / host id (or customer name/domain/email)
// into the guest; it relays only the customer id, the hub URL, the retrieval passphrase, and the
// per-guest local-API handle.
const SchemaV2 = "felhom.bootstrap/v2"

// Doc is the bootstrap.json the agent emits. Field names + json tags MUST match the controller's
// internal/bootstrap.Bootstrap exactly. It carries ONLY what the controller needs to PULL its config
// (customer id + hub url + retrieval passphrase) and reach the agent's local API — no registry
// credential (image is baked), no customer-scoped hub key, no CF tokens (those come from the pull).
type Doc struct {
	Schema   string      `json:"schema"`
	Customer DocCustomer `json:"customer"`
	Hub      DocHub      `json:"hub"`
	LocalAPI DocLocalAPI `json:"local_api"`
}

type DocCustomer struct {
	ID string `json:"id"` // the pull target; the hub provides name/domain/email
}

type DocHub struct {
	URL               string `json:"url"`
	RetrievalPassword string `json:"retrieval_password"` // SECRET — pulls the full config (incl. the customer key)
}

type DocLocalAPI struct {
	Endpoint    string `json:"endpoint"`    // host bridge IP:port
	Fingerprint string `json:"fingerprint"` // agent leaf-cert SHA-256 (hex) to pin
	Token       string `json:"token"`       // per-guest bearer; SECRET — written 0600 only
}

// render marshals the doc as indented JSON (the bytes written into the config mount).
func (d Doc) render() ([]byte, error) {
	return json.MarshalIndent(d, "", "  ")
}
