package httpapi

import (
	"encoding/json"
	"testing"
)

// TestFlexBoolUnmarshal covers the exact production failure: the LLM emitted
// `"privileged":0` / `"nesting":1` (numbers) and the strict bool field made the
// already-approved pct_create execution fail to parse, so the LXC was never
// created.
func TestFlexBoolUnmarshal(t *testing.T) {
	type cfg struct {
		Privileged flexBool `json:"privileged"`
		Nesting    flexBool `json:"nesting"`
	}
	cases := []struct {
		in         string
		privileged bool
		nesting    bool
		wantErr    bool
	}{
		{`{"privileged":0,"nesting":1}`, false, true, false},        // the prod payload
		{`{"privileged":false,"nesting":true}`, false, true, false}, // canonical
		{`{"privileged":"1","nesting":"0"}`, true, false, false},    // stringified
		{`{"privileged":"true","nesting":"no"}`, true, false, false},
		{`{}`, false, false, false}, // absent → zero
		{`{"privileged":"maybe"}`, false, false, true},
	}
	for _, c := range cases {
		var out cfg
		err := json.Unmarshal([]byte(c.in), &out)
		if (err != nil) != c.wantErr {
			t.Fatalf("%s: err=%v wantErr=%v", c.in, err, c.wantErr)
		}
		if c.wantErr {
			continue
		}
		if bool(out.Privileged) != c.privileged || bool(out.Nesting) != c.nesting {
			t.Errorf("%s: got priv=%v nest=%v want priv=%v nest=%v",
				c.in, bool(out.Privileged), bool(out.Nesting), c.privileged, c.nesting)
		}
	}
}

// TestJSONErrValidForNastyOutput guards the bug where command output with
// quotes/backslashes/newlines produced invalid JSON, failing the ::jsonb cast
// and silently dropping the execution's final status update.
func TestJSONErrValidForNastyOutput(t *testing.T) {
	nasty := "CT 132 already exists on node \"hubris\"\n\tpath C:\\x\r\n\x00 100%"
	for _, payload := range [][]byte{
		jsonErr("%s", nasty),
		jsonErr("list templates on %s: %s", "host:strong", nasty),
	} {
		var m map[string]any
		if err := json.Unmarshal(payload, &m); err != nil {
			t.Fatalf("jsonErr produced invalid JSON: %v\npayload=%s", err, payload)
		}
		if _, ok := m["error"]; !ok {
			t.Errorf("missing error key: %s", payload)
		}
	}
}

// resolveTemplate and gatewayPreflightPassed moved to the ssh provisioner
// adapter with the pct flow (Phase 7); their tests live in
// internal/adapters/ssh/provisioner_test.go.
//
// provisionScript and sanitizePkgs were removed when pct_create was made
// atomic (create + start + register only) — installing packages and running
// setup scripts is now the agent's own job via follow-up `run` calls, which
// already has its own classifier/sanitization tests in internal/policy.
