package canon_test

import (
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"os"
	"path/filepath"
	"testing"

	"github.com/stretchr/testify/require"
)

// requestFixture captures one stable canonical-bytes test vector for a v1
// authenticated request. Fixture files live under testdata/ and are
// generated by hand using the canon package itself; they are committed as
// golden data so every change to the canonical-bytes contract surfaces as
// a hex diff in code review.
type requestFixture struct {
	MessageType               string `json:"message_type"`
	ProtocolVersion           string `json:"protocol_version"`
	DeviceSessionID           string `json:"device_session_id"`
	TimestampMS               int64  `json:"timestamp_ms"`
	RequestID                 string `json:"request_id"`
	Payload                   string `json:"payload"`
	PayloadHashHex            string `json:"payload_hash_hex"`
	ExpectedCanonicalBytesHex string `json:"expected_canonical_bytes_hex"`
	PrivateKeySeedHex         string `json:"private_key_seed_hex"`
	PublicKeyBase64           string `json:"public_key_base64"`
	ExpectedSignatureHex      string `json:"expected_signature_hex"`
}

type responseFixture struct {
	ProtocolVersion           string `json:"protocol_version"`
	RequestID                 string `json:"request_id"`
	TimestampMS               int64  `json:"timestamp_ms"`
	ResultCode                string `json:"result_code"`
	Payload                   string `json:"payload"`
	PayloadHashHex            string `json:"payload_hash_hex"`
	ExpectedCanonicalBytesHex string `json:"expected_canonical_bytes_hex"`
	PrivateKeySeedHex         string `json:"private_key_seed_hex"`
	PublicKeyBase64           string `json:"public_key_base64"`
	ExpectedSignatureHex      string `json:"expected_signature_hex"`
}

type eventFixture struct {
	EventType                 string `json:"event_type"`
	EventID                   string `json:"event_id"`
	TimestampMS               int64  `json:"timestamp_ms"`
	RequestID                 string `json:"request_id"`
	TraceID                   string `json:"trace_id"`
	Payload                   string `json:"payload"`
	PayloadHashHex            string `json:"payload_hash_hex"`
	ExpectedCanonicalBytesHex string `json:"expected_canonical_bytes_hex"`
	PrivateKeySeedHex         string `json:"private_key_seed_hex"`
	PublicKeyBase64           string `json:"public_key_base64"`
	ExpectedSignatureHex      string `json:"expected_signature_hex"`
}

func loadJSONFixture(t *testing.T, name string, into any) {
	t.Helper()

	body, err := os.ReadFile(filepath.Join("testdata", name))
	require.NoError(t, err, "read %s", name)
	require.NoError(t, json.Unmarshal(body, into), "decode %s", name)
}

func mustHex(t *testing.T, value string) []byte {
	t.Helper()

	decoded, err := hex.DecodeString(value)
	require.NoError(t, err)

	return decoded
}

func sha256Sum(payload []byte) []byte {
	sum := sha256.Sum256(payload)
	return sum[:]
}
